Implement Cast Streaming mirroring, DLNA casting, daemon+GUI, and breadd integration
Some checks failed
dev release / build (push) Failing after 12s
Some checks failed
dev release / build (push) Failing after 12s
Builds out the full v1 scope: a vendored+patched openscreen subset for low-latency Cast Streaming (Mirroring receiver 0F5096E8) alongside the existing Cast V2/HLS and new DLNA/AVTransport casting paths, breadcastd's Idle/Casting state machine with a private IPC socket, the breadcast GTK4 popup as a thin IPC client, and bread.cast.*/bread.command.cast.* breadd integration (device discovery, start/stop, mirroring lifecycle events). Also adds bakery/systemd/Forgejo CI packaging. Validated end-to-end against a real Chromecast/Google TV: negotiated Cast Streaming session, live pipeline playback, and daemon+GUI click-to-cast/ stop through the actual popup.
This commit is contained in:
parent
887c29002f
commit
8c745d18e0
283 changed files with 36788 additions and 0 deletions
20
breadcast-caststream-sys/vendor/openscreen/platform/base/compiler_specific.h
vendored
Normal file
20
breadcast-caststream-sys/vendor/openscreen/platform/base/compiler_specific.h
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_COMPILER_SPECIFIC_H_
|
||||
#define PLATFORM_BASE_COMPILER_SPECIFIC_H_
|
||||
|
||||
#ifdef NOINLINE
|
||||
#define OSP_NOINLINE NOINLINE
|
||||
#elif __has_cpp_attribute(clang::noinline)
|
||||
#define OSP_NOINLINE [[clang::noinline]]
|
||||
#elif __has_cpp_attribute(gnu::noinline)
|
||||
#define OSP_NOINLINE [[gnu::noinline]]
|
||||
#elif __has_cpp_attribute(msvc::noinline)
|
||||
#define OSP_NOINLINE [[msvc::noinline]]
|
||||
#else
|
||||
#define OSP_NOINLINE __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
#endif // PLATFORM_BASE_COMPILER_SPECIFIC_H_
|
||||
306
breadcast-caststream-sys/vendor/openscreen/platform/base/error.cc
vendored
Normal file
306
breadcast-caststream-sys/vendor/openscreen/platform/base/error.cc
vendored
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/error.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
Error::Error() = default;
|
||||
|
||||
Error::Error(const Error& error) = default;
|
||||
|
||||
Error::Error(Error&& error) noexcept = default;
|
||||
|
||||
Error::Error(Code code) : code_(code) {}
|
||||
|
||||
Error::Error(Code code, const std::string& message)
|
||||
: code_(code), message_(message) {}
|
||||
|
||||
Error::Error(Code code, std::string&& message)
|
||||
: code_(code), message_(std::move(message)) {}
|
||||
|
||||
Error::~Error() = default;
|
||||
|
||||
Error& Error::operator=(const Error& other) = default;
|
||||
|
||||
Error& Error::operator=(Error&& other) = default;
|
||||
|
||||
bool Error::operator==(const Error& other) const {
|
||||
return code_ == other.code_ && message_ == other.message_;
|
||||
}
|
||||
|
||||
bool Error::operator!=(const Error& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool Error::operator==(Code code) const {
|
||||
return code_ == code;
|
||||
}
|
||||
|
||||
bool Error::operator!=(Code code) const {
|
||||
return !(*this == code);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Error::Code& code) {
|
||||
if (code == Error::Code::kNone) {
|
||||
return os << "Success";
|
||||
}
|
||||
os << "Failure: ";
|
||||
switch (code) {
|
||||
case Error::Code::kAgain:
|
||||
return os << "Transient";
|
||||
case Error::Code::kCborParsing:
|
||||
return os << "CborParsing";
|
||||
case Error::Code::kCborEncoding:
|
||||
return os << "CborEncoding";
|
||||
case Error::Code::kCborIncompleteMessage:
|
||||
return os << "CborIncompleteMessage";
|
||||
case Error::Code::kCborInvalidMessage:
|
||||
return os << "CborInvalidMessage";
|
||||
case Error::Code::kCborInvalidResponseId:
|
||||
return os << "CborInvalidResponseId";
|
||||
case Error::Code::kNoAvailableReceivers:
|
||||
return os << "NoAvailableReceivers";
|
||||
case Error::Code::kRequestCancelled:
|
||||
return os << "RequestCancelled";
|
||||
case Error::Code::kNoPresentationFound:
|
||||
return os << "NoPresentationFound";
|
||||
case Error::Code::kPreviousStartInProgress:
|
||||
return os << "PreviousStartInProgress";
|
||||
case Error::Code::kUnknownStartError:
|
||||
return os << "UnknownStartError";
|
||||
case Error::Code::kUnknownRequestId:
|
||||
return os << "UnknownRequestId";
|
||||
case Error::Code::kAddressInUse:
|
||||
return os << "AddressInUse";
|
||||
case Error::Code::kDomainNameTooLong:
|
||||
return os << "DomainNameTooLong";
|
||||
case Error::Code::kDomainNameLabelTooLong:
|
||||
return os << "DomainNameLabelTooLong";
|
||||
case Error::Code::kIOFailure:
|
||||
return os << "IOFailure";
|
||||
case Error::Code::kInitializationFailure:
|
||||
return os << "InitializationFailure";
|
||||
case Error::Code::kInvalidIPV4Address:
|
||||
return os << "InvalidIPV4Address";
|
||||
case Error::Code::kInvalidIPV6Address:
|
||||
return os << "InvalidIPV6Address";
|
||||
case Error::Code::kConnectionFailed:
|
||||
return os << "ConnectionFailed";
|
||||
case Error::Code::kSocketOptionSettingFailure:
|
||||
return os << "SocketOptionSettingFailure";
|
||||
case Error::Code::kSocketAcceptFailure:
|
||||
return os << "SocketAcceptFailure";
|
||||
case Error::Code::kSocketBindFailure:
|
||||
return os << "SocketBindFailure";
|
||||
case Error::Code::kSocketClosedFailure:
|
||||
return os << "SocketClosedFailure";
|
||||
case Error::Code::kSocketConnectFailure:
|
||||
return os << "SocketConnectFailure";
|
||||
case Error::Code::kSocketInvalidState:
|
||||
return os << "SocketInvalidState";
|
||||
case Error::Code::kSocketListenFailure:
|
||||
return os << "SocketListenFailure";
|
||||
case Error::Code::kSocketReadFailure:
|
||||
return os << "SocketReadFailure";
|
||||
case Error::Code::kSocketSendFailure:
|
||||
return os << "SocketSendFailure";
|
||||
case Error::Code::kMdnsRegisterFailure:
|
||||
return os << "MdnsRegisterFailure";
|
||||
case Error::Code::kMdnsReadFailure:
|
||||
return os << "MdnsReadFailure";
|
||||
case Error::Code::kMdnsNonConformingFailure:
|
||||
return os << "kMdnsNonConformingFailure";
|
||||
case Error::Code::kParseError:
|
||||
return os << "ParseError";
|
||||
case Error::Code::kUnknownMessageType:
|
||||
return os << "UnknownMessageType";
|
||||
case Error::Code::kNoActiveConnection:
|
||||
return os << "NoActiveConnection";
|
||||
case Error::Code::kAlreadyClosed:
|
||||
return os << "AlreadyClosed";
|
||||
case Error::Code::kNoStartedPresentation:
|
||||
return os << "NoStartedPresentation";
|
||||
case Error::Code::kPresentationAlreadyStarted:
|
||||
return os << "PresentationAlreadyStarted";
|
||||
case Error::Code::kInvalidConnectionState:
|
||||
return os << "InvalidConnectionState";
|
||||
case Error::Code::kJsonParseError:
|
||||
return os << "JsonParseError";
|
||||
case Error::Code::kJsonWriteError:
|
||||
return os << "JsonWriteError";
|
||||
case Error::Code::kFatalSSLError:
|
||||
return os << "FatalSSLError";
|
||||
case Error::Code::kRSAKeyGenerationFailure:
|
||||
return os << "RSAKeyGenerationFailure";
|
||||
case Error::Code::kRSAKeyParseError:
|
||||
return os << "RSAKeyParseError";
|
||||
case Error::Code::kEVPInitializationError:
|
||||
return os << "EVPInitializationError";
|
||||
case Error::Code::kCertificateCreationError:
|
||||
return os << "CertificateCreationError";
|
||||
case Error::Code::kCertificateValidationError:
|
||||
return os << "CertificateValidationError";
|
||||
case Error::Code::kSha256HashFailure:
|
||||
return os << "Sha256HashFailure";
|
||||
case Error::Code::kFileLoadFailure:
|
||||
return os << "FileLoadFailure";
|
||||
case Error::Code::kErrCertsMissing:
|
||||
return os << "ErrCertsMissing";
|
||||
case Error::Code::kErrCertsParse:
|
||||
return os << "ErrCertsParse";
|
||||
case Error::Code::kErrCertsRestrictions:
|
||||
return os << "ErrCertsRestrictions";
|
||||
case Error::Code::kErrCertsDateInvalid:
|
||||
return os << "ErrCertsDateInvalid";
|
||||
case Error::Code::kErrCertsVerifyGeneric:
|
||||
return os << "ErrCertsVerifyGeneric";
|
||||
case Error::Code::kErrCertsVerifyUntrustedCert:
|
||||
return os << "kErrCertsVerifyUntrustedCert";
|
||||
case Error::Code::kErrCrlInvalid:
|
||||
return os << "ErrCrlInvalid";
|
||||
case Error::Code::kErrCertsRevoked:
|
||||
return os << "ErrCertsRevoked";
|
||||
case Error::Code::kErrCertsPathlen:
|
||||
return os << "ErrCertsPathlen";
|
||||
case Error::Code::kErrCertSerialize:
|
||||
return os << "ErrCertSerialize";
|
||||
case Error::Code::kCastV2PeerCertEmpty:
|
||||
return os << "kCastV2PeerCertEmpty";
|
||||
case Error::Code::kCastV2WrongPayloadType:
|
||||
return os << "kCastV2WrongPayloadType";
|
||||
case Error::Code::kCastV2NoPayload:
|
||||
return os << "kCastV2NoPayload";
|
||||
case Error::Code::kCastV2PayloadParsingFailed:
|
||||
return os << "kCastV2PayloadParsingFailed";
|
||||
case Error::Code::kCastV2MessageError:
|
||||
return os << "CastV2kMessageError";
|
||||
case Error::Code::kCastV2NoResponse:
|
||||
return os << "kCastV2NoResponse";
|
||||
case Error::Code::kCastV2FingerprintNotFound:
|
||||
return os << "kCastV2FingerprintNotFound";
|
||||
case Error::Code::kCastV2CertNotSignedByTrustedCa:
|
||||
return os << "kCastV2CertNotSignedByTrustedCa";
|
||||
case Error::Code::kCastV2CannotExtractPublicKey:
|
||||
return os << "kCastV2CannotExtractPublicKey";
|
||||
case Error::Code::kCastV2SignedBlobsMismatch:
|
||||
return os << "kCastV2SignedBlobsMismatch";
|
||||
case Error::Code::kCastV2TlsCertValidityPeriodTooLong:
|
||||
return os << "kCastV2TlsCertValidityPeriodTooLong";
|
||||
case Error::Code::kCastV2TlsCertValidStartDateInFuture:
|
||||
return os << "kCastV2TlsCertValidStartDateInFuture";
|
||||
case Error::Code::kCastV2TlsCertExpired:
|
||||
return os << "kCastV2TlsCertExpired";
|
||||
case Error::Code::kCastV2SenderNonceMismatch:
|
||||
return os << "kCastV2SenderNonceMismatch";
|
||||
case Error::Code::kCastV2DigestUnsupported:
|
||||
return os << "kCastV2DigestUnsupported";
|
||||
case Error::Code::kCastV2SignatureEmpty:
|
||||
return os << "kCastV2SignatureEmpty";
|
||||
case Error::Code::kCastV2ChannelNotOpen:
|
||||
return os << "kCastV2ChannelNotOpen";
|
||||
case Error::Code::kCastV2AuthenticationError:
|
||||
return os << "kCastV2AuthenticationError";
|
||||
case Error::Code::kCastV2ConnectError:
|
||||
return os << "kCastV2ConnectError";
|
||||
case Error::Code::kCastV2CastSocketError:
|
||||
return os << "kCastV2CastSocketError";
|
||||
case Error::Code::kCastV2TransportError:
|
||||
return os << "kCastV2TransportError";
|
||||
case Error::Code::kCastV2InvalidMessage:
|
||||
return os << "kCastV2InvalidMessage";
|
||||
case Error::Code::kCastV2InvalidChannelId:
|
||||
return os << "kCastV2InvalidChannelId";
|
||||
case Error::Code::kCastV2ConnectTimeout:
|
||||
return os << "kCastV2ConnectTimeout";
|
||||
case Error::Code::kCastV2PingTimeout:
|
||||
return os << "kCastV2PingTimeout";
|
||||
case Error::Code::kCastV2ChannelPolicyMismatch:
|
||||
return os << "kCastV2ChannelPolicyMismatch";
|
||||
case Error::Code::kCreateSignatureFailed:
|
||||
return os << "kCreateSignatureFailed";
|
||||
case Error::Code::kUpdateReceivedRecordFailure:
|
||||
return os << "kUpdateReceivedRecordFailure";
|
||||
case Error::Code::kRecordPublicationError:
|
||||
return os << "kRecordPublicationError";
|
||||
case Error::Code::kProcessReceivedRecordFailure:
|
||||
return os << "ProcessReceivedRecordFailure";
|
||||
case Error::Code::kUnknownError:
|
||||
return os << "UnknownError";
|
||||
case Error::Code::kNotImplemented:
|
||||
return os << "NotImplemented";
|
||||
case Error::Code::kInsufficientBuffer:
|
||||
return os << "InsufficientBuffer";
|
||||
case Error::Code::kParameterInvalid:
|
||||
return os << "ParameterInvalid";
|
||||
case Error::Code::kParameterOutOfRange:
|
||||
return os << "ParameterOutOfRange";
|
||||
case Error::Code::kParameterNullPointer:
|
||||
return os << "ParameterNullPointer";
|
||||
case Error::Code::kIndexOutOfBounds:
|
||||
return os << "IndexOutOfBounds";
|
||||
case Error::Code::kItemAlreadyExists:
|
||||
return os << "ItemAlreadyExists";
|
||||
case Error::Code::kItemNotFound:
|
||||
return os << "ItemNotFound";
|
||||
case Error::Code::kOperationInvalid:
|
||||
return os << "OperationInvalid";
|
||||
case Error::Code::kOperationInProgress:
|
||||
return os << "OperationInProgress";
|
||||
case Error::Code::kOperationCancelled:
|
||||
return os << "OperationCancelled";
|
||||
case Error::Code::kInterrupted:
|
||||
return os << "Interrupted";
|
||||
case Error::Code::kUnknownCodec:
|
||||
return os << "UnknownCodec";
|
||||
case Error::Code::kInvalidCodecParameter:
|
||||
return os << "InvalidCodecParameter";
|
||||
case Error::Code::kSocketFailure:
|
||||
return os << "SocketFailure";
|
||||
case Error::Code::kUnencryptedOffer:
|
||||
return os << "UnencryptedOffer";
|
||||
case Error::Code::kRemotingNotSupported:
|
||||
return os << "RemotingNotSupported";
|
||||
case Error::Code::kNoStreamSelected:
|
||||
return os << "NoStreamSelected";
|
||||
case Error::Code::kAnswerTimeout:
|
||||
return os << "AnswerTimeout";
|
||||
case Error::Code::kInvalidAnswer:
|
||||
return os << "InvalidAnswer";
|
||||
case Error::Code::kMessageTimeout:
|
||||
return os << "MessageTimeout";
|
||||
case Error::Code::kNone:
|
||||
break;
|
||||
}
|
||||
|
||||
// Unused 'return' to get around failure on GCC.
|
||||
return os;
|
||||
}
|
||||
|
||||
std::string Error::ToString() const {
|
||||
std::stringstream ss;
|
||||
ss << *this;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string ToString(openscreen::Error::Code code) {
|
||||
std::ostringstream ss;
|
||||
ss << code;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Error& error) {
|
||||
out << error.code() << " = \"" << error.message() << "\"";
|
||||
return out;
|
||||
}
|
||||
|
||||
// static
|
||||
const Error& Error::None() {
|
||||
static Error& error = *new Error(Code::kNone);
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace openscreen
|
||||
432
breadcast-caststream-sys/vendor/openscreen/platform/base/error.h
vendored
Normal file
432
breadcast-caststream-sys/vendor/openscreen/platform/base/error.h
vendored
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_ERROR_H_
|
||||
#define PLATFORM_BASE_ERROR_H_
|
||||
|
||||
#include <cassert>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
// Represents an error returned by an OSP library operation. An error has a
|
||||
// code and an optional message.
|
||||
class Error {
|
||||
public:
|
||||
// TODO(crbug.com/openscreen/65): Group/rename OSP-specific errors
|
||||
// NOTE: new values should be added to the end of the of enum and existing
|
||||
// values should not be changed.
|
||||
enum class Code : int8_t {
|
||||
// No error occurred.
|
||||
kNone = 0,
|
||||
|
||||
// A transient condition prevented the operation from proceeding (e.g.,
|
||||
// cannot send on a non-blocking socket without blocking). This indicates
|
||||
// the caller should try again later.
|
||||
kAgain = -1,
|
||||
|
||||
// CBOR errors.
|
||||
kCborParsing = 1,
|
||||
kCborEncoding = 2,
|
||||
kCborIncompleteMessage = 3,
|
||||
kCborInvalidResponseId = 4,
|
||||
kCborInvalidMessage = 5,
|
||||
|
||||
// Presentation start errors.
|
||||
kNoAvailableReceivers = 6,
|
||||
kRequestCancelled = 7,
|
||||
kNoPresentationFound = 8,
|
||||
kPreviousStartInProgress = 9,
|
||||
kUnknownStartError = 10,
|
||||
kUnknownRequestId = 11,
|
||||
|
||||
kAddressInUse = 12,
|
||||
kDomainNameTooLong = 13,
|
||||
kDomainNameLabelTooLong = 14,
|
||||
|
||||
kIOFailure = 15,
|
||||
kInitializationFailure = 16,
|
||||
kInvalidIPV4Address = 17,
|
||||
kInvalidIPV6Address = 18,
|
||||
kConnectionFailed = 19,
|
||||
|
||||
kSocketOptionSettingFailure = 20,
|
||||
kSocketAcceptFailure = 21,
|
||||
kSocketBindFailure = 22,
|
||||
kSocketClosedFailure = 23,
|
||||
kSocketConnectFailure = 24,
|
||||
kSocketInvalidState = 25,
|
||||
kSocketListenFailure = 26,
|
||||
kSocketReadFailure = 27,
|
||||
kSocketSendFailure = 28,
|
||||
|
||||
// MDNS errors.
|
||||
kMdnsRegisterFailure = 29,
|
||||
kMdnsReadFailure = 30,
|
||||
kMdnsNonConformingFailure = 31,
|
||||
|
||||
kParseError = 32,
|
||||
kUnknownMessageType = 33,
|
||||
|
||||
kNoActiveConnection = 34,
|
||||
kAlreadyClosed = 35,
|
||||
kInvalidConnectionState = 36,
|
||||
kNoStartedPresentation = 37,
|
||||
kPresentationAlreadyStarted = 38,
|
||||
|
||||
kJsonParseError = 39,
|
||||
kJsonWriteError = 40,
|
||||
|
||||
// OpenSSL errors.
|
||||
|
||||
// Was unable to generate an RSA key.
|
||||
kRSAKeyGenerationFailure = 41,
|
||||
kRSAKeyParseError = 42,
|
||||
|
||||
// Was unable to initialize an EVP_PKEY type.
|
||||
kEVPInitializationError = 43,
|
||||
|
||||
// Was unable to generate a certificate.
|
||||
kCertificateCreationError = 44,
|
||||
|
||||
// Certificate failed validation.
|
||||
kCertificateValidationError = 45,
|
||||
|
||||
// Failed to produce a hashing digest.
|
||||
kSha256HashFailure = 46,
|
||||
|
||||
// A non-recoverable SSL library error has occurred.
|
||||
kFatalSSLError = 47,
|
||||
kFileLoadFailure = 48,
|
||||
|
||||
// Cast certificate errors.
|
||||
|
||||
// Certificates were not provided for verification.
|
||||
kErrCertsMissing = 49,
|
||||
|
||||
// The certificates provided could not be parsed.
|
||||
kErrCertsParse = 50,
|
||||
|
||||
// Key usage is missing or is not set to Digital Signature.
|
||||
// This error could also be thrown if the CN is missing.
|
||||
kErrCertsRestrictions = 51,
|
||||
|
||||
// The current date is before the notBefore date or after the notAfter date.
|
||||
kErrCertsDateInvalid = 52,
|
||||
|
||||
// The certificate failed to chain to a trusted root.
|
||||
kErrCertsVerifyGeneric = 53,
|
||||
|
||||
// The certificate was not found in the trust store.
|
||||
kErrCertsVerifyUntrustedCert = 54,
|
||||
|
||||
// The CRL is missing or failed to verify.
|
||||
kErrCrlInvalid = 55,
|
||||
|
||||
// One of the certificates in the chain is revoked.
|
||||
kErrCertsRevoked = 56,
|
||||
|
||||
// The pathlen constraint of the root certificate was exceeded.
|
||||
kErrCertsPathlen = 57,
|
||||
|
||||
// The certificate provided could not be serialized.
|
||||
kErrCertSerialize = 58,
|
||||
|
||||
// Cast authentication errors.
|
||||
kCastV2PeerCertEmpty = 59,
|
||||
kCastV2WrongPayloadType = 60,
|
||||
kCastV2NoPayload = 61,
|
||||
kCastV2PayloadParsingFailed = 62,
|
||||
kCastV2MessageError = 63,
|
||||
kCastV2NoResponse = 64,
|
||||
kCastV2FingerprintNotFound = 65,
|
||||
kCastV2CertNotSignedByTrustedCa = 66,
|
||||
kCastV2CannotExtractPublicKey = 67,
|
||||
kCastV2SignedBlobsMismatch = 68,
|
||||
kCastV2TlsCertValidityPeriodTooLong = 69,
|
||||
kCastV2TlsCertValidStartDateInFuture = 70,
|
||||
kCastV2TlsCertExpired = 71,
|
||||
kCastV2SenderNonceMismatch = 72,
|
||||
kCastV2DigestUnsupported = 73,
|
||||
kCastV2SignatureEmpty = 74,
|
||||
|
||||
// Cast channel errors.
|
||||
kCastV2ChannelNotOpen = 75,
|
||||
kCastV2AuthenticationError = 76,
|
||||
kCastV2ConnectError = 77,
|
||||
kCastV2CastSocketError = 78,
|
||||
kCastV2TransportError = 79,
|
||||
kCastV2InvalidMessage = 80,
|
||||
kCastV2InvalidChannelId = 81,
|
||||
kCastV2ConnectTimeout = 82,
|
||||
kCastV2PingTimeout = 83,
|
||||
kCastV2ChannelPolicyMismatch = 84,
|
||||
|
||||
kCreateSignatureFailed = 85,
|
||||
|
||||
// Discovery errors.
|
||||
kUpdateReceivedRecordFailure = 86,
|
||||
kRecordPublicationError = 87,
|
||||
kProcessReceivedRecordFailure = 88,
|
||||
|
||||
// Generic errors.
|
||||
kUnknownError = 89,
|
||||
kNotImplemented = 90,
|
||||
kInsufficientBuffer = 91,
|
||||
kParameterInvalid = 92,
|
||||
kParameterOutOfRange = 93,
|
||||
kParameterNullPointer = 94,
|
||||
kIndexOutOfBounds = 95,
|
||||
kItemAlreadyExists = 96,
|
||||
kItemNotFound = 97,
|
||||
kOperationInvalid = 98,
|
||||
kOperationInProgress = 99,
|
||||
kOperationCancelled = 100,
|
||||
kInterrupted = 101,
|
||||
|
||||
// Cast streaming errors.
|
||||
kUnknownCodec = 102,
|
||||
kInvalidCodecParameter = 103,
|
||||
kSocketFailure = 104,
|
||||
kUnencryptedOffer = 105,
|
||||
kRemotingNotSupported = 106,
|
||||
kNoStreamSelected = 107,
|
||||
|
||||
// An Answer timeout means that the receiver failed to reply to our Offer
|
||||
// within a reasonable amount of time.
|
||||
kAnswerTimeout = 108,
|
||||
|
||||
// Received an ANSWER, but it was invalid.
|
||||
kInvalidAnswer = 109,
|
||||
|
||||
// A generic message timeout occured.
|
||||
kMessageTimeout = 110,
|
||||
};
|
||||
|
||||
Error();
|
||||
Error(const Error& error);
|
||||
Error(Error&& error) noexcept;
|
||||
|
||||
Error(Code code); // NOLINT
|
||||
Error(Code code, const std::string& message);
|
||||
Error(Code code, std::string&& message);
|
||||
~Error();
|
||||
|
||||
Error& operator=(const Error& other);
|
||||
Error& operator=(Error&& other);
|
||||
bool operator==(const Error& other) const;
|
||||
bool operator!=(const Error& other) const;
|
||||
|
||||
// Special case comparison with codes. Without this case, comparisons will
|
||||
// not work as expected, e.g.
|
||||
// const Error foo(Error::Code::kItemNotFound, "Didn't find an item");
|
||||
// foo == Error::Code::kItemNotFound is actually false.
|
||||
bool operator==(Code code) const;
|
||||
bool operator!=(Code code) const;
|
||||
bool ok() const { return code_ == Code::kNone; }
|
||||
|
||||
Code code() const { return code_; }
|
||||
const std::string& message() const { return message_; }
|
||||
std::string& message() { return message_; }
|
||||
|
||||
static const Error& None();
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
Code code_ = Code::kNone;
|
||||
std::string message_;
|
||||
};
|
||||
|
||||
std::string ToString(openscreen::Error::Code code);
|
||||
std::ostream& operator<<(std::ostream& os, const Error::Code& code);
|
||||
std::ostream& operator<<(std::ostream& out, const Error& error);
|
||||
|
||||
// A convenience function to return a single value from a function that can
|
||||
// return a value or an error. For normal results, construct with a ValueType*
|
||||
// (ErrorOr takes ownership) and the Error will be kNone with an empty message.
|
||||
// For Error results, construct with an error code and value.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// ErrorOr<Bar> Foo::DoSomething() {
|
||||
// if (success) {
|
||||
// return Bar();
|
||||
// } else {
|
||||
// return Error(kBadThingHappened, "No can do");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// TODO(mfoltz): Add support for type conversions.
|
||||
template <typename ValueType>
|
||||
class ErrorOr {
|
||||
public:
|
||||
static ErrorOr<ValueType> None() {
|
||||
static ErrorOr<ValueType> error(Error::Code::kNone);
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorOr(const ValueType& value) : value_(value), is_value_(true) {} // NOLINT
|
||||
ErrorOr(ValueType&& value) noexcept // NOLINT
|
||||
: value_(std::move(value)), is_value_(true) {}
|
||||
|
||||
ErrorOr(const Error& error) : error_(error), is_value_(false) { // NOLINT
|
||||
assert(error_.code() != Error::Code::kNone);
|
||||
}
|
||||
ErrorOr(Error&& error) noexcept // NOLINT
|
||||
: error_(std::move(error)), is_value_(false) {
|
||||
assert(error_.code() != Error::Code::kNone);
|
||||
}
|
||||
ErrorOr(Error::Code code) : error_(code), is_value_(false) { // NOLINT
|
||||
assert(error_.code() != Error::Code::kNone);
|
||||
}
|
||||
ErrorOr(Error::Code code, std::string message)
|
||||
: error_(code, std::move(message)), is_value_(false) {
|
||||
assert(error_.code() != Error::Code::kNone);
|
||||
}
|
||||
|
||||
ErrorOr(const ErrorOr& other) = delete;
|
||||
ErrorOr(ErrorOr&& other) noexcept : is_value_(other.is_value_) {
|
||||
// NB: Both `value_` and `error_` are uninitialized memory at this point!
|
||||
// Unlike the other constructors, the compiler will not auto-generate
|
||||
// constructor calls for either union member because neither appeared in
|
||||
// this constructor's initializer list.
|
||||
if (other.is_value_) {
|
||||
new (&value_) ValueType(std::move(other.value_));
|
||||
} else {
|
||||
new (&error_) Error(std::move(other.error_));
|
||||
}
|
||||
}
|
||||
|
||||
ErrorOr& operator=(const ErrorOr& other) = delete;
|
||||
ErrorOr& operator=(ErrorOr&& other) noexcept {
|
||||
this->~ErrorOr<ValueType>();
|
||||
new (this) ErrorOr<ValueType>(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
~ErrorOr() {
|
||||
// NB: `value_` or `error_` must be explicitly destroyed since the compiler
|
||||
// will not auto-generate the destructor calls for union members.
|
||||
if (is_value_) {
|
||||
value_.~ValueType();
|
||||
} else {
|
||||
error_.~Error();
|
||||
}
|
||||
}
|
||||
|
||||
bool is_error() const { return !is_value_; }
|
||||
bool is_value() const { return is_value_; }
|
||||
|
||||
// Unlike Error, we CAN provide an operator bool here, since it is
|
||||
// more obvious to callers that ErrorOr<Foo> will be true if it's Foo.
|
||||
operator bool() const { return is_value_; }
|
||||
|
||||
const Error& error() const {
|
||||
assert(!is_value_);
|
||||
return error_;
|
||||
}
|
||||
Error& error() {
|
||||
assert(!is_value_);
|
||||
return error_;
|
||||
}
|
||||
|
||||
const ValueType& value() const {
|
||||
assert(is_value_);
|
||||
return value_;
|
||||
}
|
||||
ValueType& value() {
|
||||
assert(is_value_);
|
||||
return value_;
|
||||
}
|
||||
|
||||
// Move only value or fallback
|
||||
ValueType&& value(ValueType&& fallback) {
|
||||
if (is_value()) {
|
||||
return std::move(value());
|
||||
}
|
||||
return std::forward<ValueType>(fallback);
|
||||
}
|
||||
|
||||
// Copy only value or fallback
|
||||
ValueType value(ValueType fallback) const {
|
||||
if (is_value()) {
|
||||
return value();
|
||||
}
|
||||
return std::move(fallback);
|
||||
}
|
||||
|
||||
private:
|
||||
// Only one of these is an active member, determined by `is_value_`. Since
|
||||
// they are union'ed, they must be explicitly constructed and destroyed.
|
||||
union {
|
||||
ValueType value_;
|
||||
Error error_;
|
||||
};
|
||||
|
||||
// If true, `value_` is initialized and active. Otherwise, `error_` is
|
||||
// initialized and active.
|
||||
const bool is_value_;
|
||||
};
|
||||
|
||||
// Define comparison operators using SFINAE.
|
||||
template <typename ValueType>
|
||||
bool operator<(const ErrorOr<ValueType>& lhs, const ErrorOr<ValueType>& rhs) {
|
||||
// Handle the cases where one side is an error.
|
||||
if (lhs.is_error() != rhs.is_error()) {
|
||||
return lhs.is_error();
|
||||
}
|
||||
|
||||
// Handle the case where both sides are errors.
|
||||
if (lhs.is_error()) {
|
||||
return static_cast<int8_t>(lhs.error().code()) <
|
||||
static_cast<int8_t>(rhs.error().code());
|
||||
}
|
||||
|
||||
// Handle the case where both are values.
|
||||
return lhs.value() < rhs.value();
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool operator>(const ErrorOr<ValueType>& lhs, const ErrorOr<ValueType>& rhs) {
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool operator<=(const ErrorOr<ValueType>& lhs, const ErrorOr<ValueType>& rhs) {
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool operator>=(const ErrorOr<ValueType>& lhs, const ErrorOr<ValueType>& rhs) {
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool operator==(const ErrorOr<ValueType>& lhs, const ErrorOr<ValueType>& rhs) {
|
||||
// Handle the cases where one side is an error.
|
||||
if (lhs.is_error() != rhs.is_error()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle the case where both sides are errors.
|
||||
if (lhs.is_error()) {
|
||||
return lhs.error() == rhs.error();
|
||||
}
|
||||
|
||||
// Handle the case where both are values.
|
||||
return lhs.value() == rhs.value();
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool operator!=(const ErrorOr<ValueType>& lhs, const ErrorOr<ValueType>& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_ERROR_H_
|
||||
98
breadcast-caststream-sys/vendor/openscreen/platform/base/interface_info.cc
vendored
Normal file
98
breadcast-caststream-sys/vendor/openscreen/platform/base/interface_info.cc
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/interface_info.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
InterfaceInfo::InterfaceInfo() = default;
|
||||
InterfaceInfo::InterfaceInfo(NetworkInterfaceIndex index,
|
||||
const uint8_t hardware_address[6],
|
||||
std::string name,
|
||||
Type type,
|
||||
std::vector<IPSubnet> addresses)
|
||||
: index(index),
|
||||
hardware_address{hardware_address[0], hardware_address[1],
|
||||
hardware_address[2], hardware_address[3],
|
||||
hardware_address[4], hardware_address[5]},
|
||||
name(std::move(name)),
|
||||
type(type),
|
||||
addresses(std::move(addresses)) {}
|
||||
InterfaceInfo::~InterfaceInfo() = default;
|
||||
|
||||
IPSubnet::IPSubnet() = default;
|
||||
IPSubnet::IPSubnet(IPAddress address, uint8_t prefix_length)
|
||||
: address(std::move(address)), prefix_length(prefix_length) {}
|
||||
IPSubnet::~IPSubnet() = default;
|
||||
|
||||
IPAddress InterfaceInfo::GetIpAddressV4() const {
|
||||
for (const auto& address : addresses) {
|
||||
if (address.address.IsV4()) {
|
||||
return address.address;
|
||||
}
|
||||
}
|
||||
return IPAddress{};
|
||||
}
|
||||
|
||||
IPAddress InterfaceInfo::GetIpAddressV6() const {
|
||||
for (const auto& address : addresses) {
|
||||
if (address.address.IsV6()) {
|
||||
return address.address;
|
||||
}
|
||||
}
|
||||
return IPAddress{};
|
||||
}
|
||||
|
||||
bool InterfaceInfo::HasHardwareAddress() const {
|
||||
return std::any_of(hardware_address.begin(), hardware_address.end(),
|
||||
[](uint8_t e) { return e != 0; });
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const IPSubnet& subnet) {
|
||||
if (subnet.address.IsV6()) {
|
||||
out << '[';
|
||||
}
|
||||
out << subnet.address;
|
||||
if (subnet.address.IsV6()) {
|
||||
out << ']';
|
||||
}
|
||||
return out << '/' << std::dec << static_cast<int>(subnet.prefix_length);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, InterfaceInfo::Type type) {
|
||||
switch (type) {
|
||||
case InterfaceInfo::Type::kEthernet:
|
||||
out << "Ethernet";
|
||||
break;
|
||||
case InterfaceInfo::Type::kWifi:
|
||||
out << "Wifi";
|
||||
break;
|
||||
case InterfaceInfo::Type::kLoopback:
|
||||
out << "Loopback";
|
||||
break;
|
||||
case InterfaceInfo::Type::kOther:
|
||||
out << "Other";
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const InterfaceInfo& info) {
|
||||
out << '{' << info.index << " (a.k.a. " << info.name
|
||||
<< "); media_type=" << info.type << "; MAC=" << std::hex
|
||||
<< static_cast<int>(info.hardware_address[0]);
|
||||
for (size_t i = 1; i < info.hardware_address.size(); ++i) {
|
||||
out << ':' << static_cast<int>(info.hardware_address[i]);
|
||||
}
|
||||
for (const IPSubnet& ip : info.addresses) {
|
||||
out << "; " << ip;
|
||||
}
|
||||
return out << '}';
|
||||
}
|
||||
|
||||
} // namespace openscreen
|
||||
86
breadcast-caststream-sys/vendor/openscreen/platform/base/interface_info.h
vendored
Normal file
86
breadcast-caststream-sys/vendor/openscreen/platform/base/interface_info.h
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_INTERFACE_INFO_H_
|
||||
#define PLATFORM_BASE_INTERFACE_INFO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "platform/base/ip_address.h"
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
// Unique identifier, usually provided by the operating system, for identifying
|
||||
// a specific network interface. This value is used with UdpSocket to join
|
||||
// multicast groups, or to make multicast broadcasts. An implementation may
|
||||
// choose to make these values anything its UdpSocket implementation will
|
||||
// recognize.
|
||||
using NetworkInterfaceIndex = int64_t;
|
||||
enum : NetworkInterfaceIndex { kInvalidNetworkInterfaceIndex = -1 };
|
||||
|
||||
struct IPSubnet {
|
||||
IPAddress address;
|
||||
|
||||
// Prefix length of `address`, which is another way of specifying a subnet
|
||||
// mask. For example, 192.168.0.10/24 is a common representation of the
|
||||
// address 192.168.0.10 with a 24-bit prefix (this describes a range of IPv4
|
||||
// addresses from 192.168.0.0 through 192.168.0.255). Likewise, for IPv6
|
||||
// addresses such as 2001:db8::/96, the concept is the same (this specifies
|
||||
// the range of addresses having the same leading 96 bits).
|
||||
uint8_t prefix_length = 0;
|
||||
|
||||
IPSubnet();
|
||||
IPSubnet(IPAddress address, uint8_t prefix);
|
||||
~IPSubnet();
|
||||
};
|
||||
|
||||
struct InterfaceInfo {
|
||||
enum class Type : uint32_t { kEthernet = 0, kWifi, kLoopback, kOther };
|
||||
|
||||
// Interface index, typically as specified by the operating system,
|
||||
// identifying this interface on the host machine.
|
||||
NetworkInterfaceIndex index = kInvalidNetworkInterfaceIndex;
|
||||
|
||||
// MAC address of the interface. Typically 6 or 16 bytes. Empty if
|
||||
// unavailable.
|
||||
std::vector<uint8_t> hardware_address;
|
||||
|
||||
// Interface name (e.g. eth0) if available.
|
||||
std::string name;
|
||||
|
||||
// Hardware type of the interface.
|
||||
Type type = Type::kOther;
|
||||
|
||||
// All IP addresses associated with the interface.
|
||||
std::vector<IPSubnet> addresses;
|
||||
|
||||
// Returns an IPAddress of the given type associated with this network
|
||||
// interface, or the false IPAddress if the associated address family is not
|
||||
// supported on this interface.
|
||||
IPAddress GetIpAddressV4() const;
|
||||
IPAddress GetIpAddressV6() const;
|
||||
|
||||
// Returns true if `hardware_address` is non-zero.
|
||||
bool HasHardwareAddress() const;
|
||||
|
||||
InterfaceInfo();
|
||||
InterfaceInfo(NetworkInterfaceIndex index,
|
||||
const uint8_t hardware_address[6],
|
||||
std::string name,
|
||||
Type type,
|
||||
std::vector<IPSubnet> addresses);
|
||||
~InterfaceInfo();
|
||||
};
|
||||
|
||||
// Human-readable output (e.g., for logging).
|
||||
std::ostream& operator<<(std::ostream& out, InterfaceInfo::Type type);
|
||||
std::ostream& operator<<(std::ostream& out, const IPSubnet& subnet);
|
||||
std::ostream& operator<<(std::ostream& out, const InterfaceInfo& info);
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_INTERFACE_INFO_H_
|
||||
343
breadcast-caststream-sys/vendor/openscreen/platform/base/ip_address.cc
vendored
Normal file
343
breadcast-caststream-sys/vendor/openscreen/platform/base/ip_address.cc
vendored
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/ip_address.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <charconv>
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#if BUILDFLAG(IS_POSIX)
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
IPAddress::IPAddress(Version version, std::span<const uint8_t> bytes)
|
||||
: version_(version) {
|
||||
assert(bytes.size() >= size());
|
||||
std::copy_n(bytes.begin(), size(), bytes_.begin());
|
||||
}
|
||||
|
||||
bool IPAddress::operator==(const IPAddress& o) const {
|
||||
return version_ == o.version_ &&
|
||||
std::equal(bytes_.begin(), bytes_.begin() + size(),
|
||||
o.bytes_.begin()) &&
|
||||
scope_id_ == o.scope_id_;
|
||||
}
|
||||
|
||||
bool IPAddress::operator!=(const IPAddress& o) const {
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
IPAddress::operator bool() const {
|
||||
return std::any_of(bytes_.begin(), bytes_.begin() + size(),
|
||||
[](uint8_t byte) { return byte; });
|
||||
}
|
||||
|
||||
void IPAddress::CopyTo(std::span<uint8_t> bytes) const {
|
||||
assert(bytes.size() >= size());
|
||||
std::copy_n(bytes_.begin(), size(), bytes.begin());
|
||||
}
|
||||
|
||||
bool IPAddress::IsLinkLocal() const {
|
||||
if (!IsV6()) {
|
||||
return false;
|
||||
}
|
||||
// Link-local addresses start with fe80::/10
|
||||
return (bytes_[0] == 0xfe) && ((bytes_[1] & 0xc0) == 0x80);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
ErrorOr<IPAddress> ParseV4(std::string_view s) {
|
||||
uint8_t octets[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (i > 0) {
|
||||
if (s.empty() || s.front() != '.') {
|
||||
return Error::Code::kInvalidIPV4Address;
|
||||
}
|
||||
s.remove_prefix(1);
|
||||
}
|
||||
const auto result =
|
||||
std::from_chars(s.data(), s.data() + s.size(), octets[i]);
|
||||
if (result.ec != std::errc()) {
|
||||
return Error::Code::kInvalidIPV4Address;
|
||||
}
|
||||
s.remove_prefix(result.ptr - s.data());
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
return Error::Code::kInvalidIPV4Address;
|
||||
}
|
||||
|
||||
return IPAddress(octets[0], octets[1], octets[2], octets[3]);
|
||||
}
|
||||
|
||||
// Returns the zero-expansion of a double-colon in `s` if `s` is a
|
||||
// well-formatted IPv6 address. If `s` is ill-formatted, returns *any* string
|
||||
// that is ill-formatted.
|
||||
std::string ExpandIPv6DoubleColon(std::string_view s) {
|
||||
constexpr std::string_view kDoubleColon = "::";
|
||||
const size_t double_colon_position = s.find(kDoubleColon);
|
||||
if (double_colon_position == std::string::npos) {
|
||||
return std::string(s); // Nothing to expand.
|
||||
}
|
||||
if (double_colon_position != s.rfind(kDoubleColon)) {
|
||||
return {}; // More than one occurrence of double colons is illegal.
|
||||
}
|
||||
|
||||
std::ostringstream expanded;
|
||||
const int num_single_colons = std::count(s.begin(), s.end(), ':') - 2;
|
||||
int num_zero_groups_to_insert = 8 - num_single_colons;
|
||||
if (double_colon_position != 0) {
|
||||
// abcd:0123:4567::f000:1
|
||||
// ^^^^^^^^^^^^^^^
|
||||
expanded << s.substr(0, double_colon_position + 1);
|
||||
--num_zero_groups_to_insert;
|
||||
}
|
||||
if (double_colon_position != (s.size() - 2)) {
|
||||
--num_zero_groups_to_insert;
|
||||
}
|
||||
while (--num_zero_groups_to_insert > 0) {
|
||||
expanded << "0:";
|
||||
}
|
||||
expanded << '0';
|
||||
if (double_colon_position != (s.size() - 2)) {
|
||||
// abcd:0123:4567::f000:1
|
||||
// ^^^^^^^
|
||||
expanded << s.substr(double_colon_position + 1);
|
||||
}
|
||||
return expanded.str();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ErrorOr<IPAddress> ParseV6(std::string_view s) {
|
||||
std::string_view address_part = s;
|
||||
uint32_t scope_id = 0;
|
||||
|
||||
// Handle link-local addresses with scope ID, e.g., fe80::1%eth0
|
||||
const size_t scope_pos = s.find('%');
|
||||
if (scope_pos != std::string::npos) {
|
||||
address_part = s.substr(0, scope_pos);
|
||||
std::string_view scope_name = s.substr(scope_pos + 1);
|
||||
#if BUILDFLAG(IS_POSIX)
|
||||
scope_id = if_nametoindex(std::string(scope_name).c_str());
|
||||
#endif
|
||||
if (scope_id == 0) {
|
||||
// If if_nametoindex failed or is not available, try parsing as a number.
|
||||
unsigned int parsed_id = 0;
|
||||
const auto result = std::from_chars(
|
||||
scope_name.data(), scope_name.data() + scope_name.size(), parsed_id);
|
||||
|
||||
if (result.ec == std::errc() &&
|
||||
result.ptr == scope_name.data() + scope_name.size() &&
|
||||
parsed_id > 0) {
|
||||
scope_id = parsed_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (scope_id == 0) {
|
||||
return Error::Code::kInvalidIPV6Address;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string scan_input = ExpandIPv6DoubleColon(address_part);
|
||||
std::string_view scan_view(scan_input);
|
||||
uint16_t hextets[8];
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (i > 0) {
|
||||
if (scan_view.empty() || scan_view.front() != ':') {
|
||||
return Error::Code::kInvalidIPV6Address;
|
||||
}
|
||||
scan_view.remove_prefix(1);
|
||||
}
|
||||
const auto result = std::from_chars(
|
||||
scan_view.data(), scan_view.data() + scan_view.size(), hextets[i], 16);
|
||||
if (result.ec != std::errc()) {
|
||||
return Error::Code::kInvalidIPV6Address;
|
||||
}
|
||||
scan_view.remove_prefix(result.ptr - scan_view.data());
|
||||
}
|
||||
|
||||
if (!scan_view.empty()) {
|
||||
return Error::Code::kInvalidIPV6Address;
|
||||
}
|
||||
|
||||
IPAddress address(hextets);
|
||||
if (scope_id != 0) {
|
||||
if (!address.IsLinkLocal()) {
|
||||
return Error::Code::kInvalidIPV6Address;
|
||||
}
|
||||
address.scope_id_ = scope_id;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
// static
|
||||
ErrorOr<IPAddress> IPAddress::Parse(std::string_view s) {
|
||||
ErrorOr<IPAddress> v4 = ParseV4(s);
|
||||
|
||||
return v4 ? std::move(v4) : ParseV6(s);
|
||||
}
|
||||
|
||||
// static
|
||||
const IPEndpoint IPEndpoint::kAnyV4() {
|
||||
return IPEndpoint{};
|
||||
}
|
||||
|
||||
// static
|
||||
const IPEndpoint IPEndpoint::kAnyV6() {
|
||||
return IPEndpoint{IPAddress::kAnyV6(), 0};
|
||||
}
|
||||
|
||||
IPEndpoint::operator bool() const {
|
||||
return address || port;
|
||||
}
|
||||
|
||||
// static
|
||||
ErrorOr<IPEndpoint> IPEndpoint::Parse(std::string_view s) {
|
||||
// Look for the colon that separates the IP address from the port number. Note
|
||||
// that this check also guards against the case where `s` is the empty string.
|
||||
const auto colon_pos = s.rfind(':');
|
||||
if (colon_pos == std::string::npos) {
|
||||
return Error(Error::Code::kParseError, "missing colon separator");
|
||||
}
|
||||
// The colon cannot be the first nor the last character in `s` because that
|
||||
// would mean there is no address part or port part.
|
||||
if (colon_pos == 0) {
|
||||
return Error(Error::Code::kParseError, "missing address before colon");
|
||||
}
|
||||
if (colon_pos == (s.size() - 1)) {
|
||||
return Error(Error::Code::kParseError, "missing port after colon");
|
||||
}
|
||||
|
||||
ErrorOr<IPAddress> address(Error::Code::kParseError);
|
||||
if (s[0] == '[' && s[colon_pos - 1] == ']') {
|
||||
// [abcd:beef:1:1::2600]:8080
|
||||
// ^^^^^^^^^^^^^^^^^^^^^
|
||||
address = ParseV6(s.substr(1, colon_pos - 2));
|
||||
} else {
|
||||
// 127.0.0.1:22
|
||||
// ^^^^^^^^^
|
||||
address = ParseV4(s.substr(0, colon_pos));
|
||||
}
|
||||
if (address.is_error()) {
|
||||
return Error(Error::Code::kParseError, "invalid address part");
|
||||
}
|
||||
|
||||
const std::string_view port_part = s.substr(colon_pos + 1);
|
||||
int port;
|
||||
const auto result = std::from_chars(
|
||||
port_part.data(), port_part.data() + port_part.size(), port);
|
||||
if (result.ec != std::errc() ||
|
||||
result.ptr != port_part.data() + port_part.size() || port < 0 ||
|
||||
port > std::numeric_limits<uint16_t>::max()) {
|
||||
return Error(Error::Code::kParseError, "invalid port part");
|
||||
}
|
||||
|
||||
return IPEndpoint{address.value(), static_cast<uint16_t>(port)};
|
||||
}
|
||||
|
||||
bool operator==(const IPEndpoint& a, const IPEndpoint& b) {
|
||||
return (a.address == b.address) && (a.port == b.port);
|
||||
}
|
||||
|
||||
bool operator!=(const IPEndpoint& a, const IPEndpoint& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
bool IPAddress::operator<(const IPAddress& other) const {
|
||||
if (version() != other.version()) {
|
||||
return version() < other.version();
|
||||
}
|
||||
|
||||
if (IsV4()) {
|
||||
return memcmp(bytes_.data(), other.bytes_.data(), 4) < 0;
|
||||
} else {
|
||||
const int cmp = memcmp(bytes_.data(), other.bytes_.data(), 16);
|
||||
if (cmp != 0) {
|
||||
return cmp < 0;
|
||||
}
|
||||
return scope_id_ < other.scope_id_;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator<(const IPEndpoint& a, const IPEndpoint& b) {
|
||||
if (a.address != b.address) {
|
||||
return a.address < b.address;
|
||||
}
|
||||
|
||||
return a.port < b.port;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const IPAddress& address) {
|
||||
char separator;
|
||||
size_t values_per_separator;
|
||||
int value_width;
|
||||
if (address.IsV4()) {
|
||||
out << std::dec;
|
||||
separator = '.';
|
||||
values_per_separator = 1;
|
||||
value_width = 0;
|
||||
} else if (address.IsV6()) {
|
||||
out << std::hex << std::setfill('0') << std::right;
|
||||
separator = ':';
|
||||
values_per_separator = 2;
|
||||
value_width = 2;
|
||||
}
|
||||
std::span<const uint8_t> bytes = address.bytes();
|
||||
for (size_t i = 0; i < bytes.size(); ++i) {
|
||||
if (i > 0 && (i % values_per_separator == 0)) {
|
||||
out << separator;
|
||||
}
|
||||
out << std::setw(value_width) << static_cast<int>(bytes[i]);
|
||||
}
|
||||
if (address.IsLinkLocal() && address.GetScopeId() != 0) {
|
||||
#if BUILDFLAG(IS_POSIX)
|
||||
char ifname[IF_NAMESIZE];
|
||||
if (if_indextoname(address.GetScopeId(), ifname)) {
|
||||
out << '%' << ifname;
|
||||
} else {
|
||||
out << '%' << address.GetScopeId();
|
||||
}
|
||||
#else
|
||||
out << '%' << address.GetScopeId();
|
||||
#endif
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const IPEndpoint& endpoint) {
|
||||
if (endpoint.address.IsV6()) {
|
||||
out << '[';
|
||||
}
|
||||
out << endpoint.address;
|
||||
if (endpoint.address.IsV6()) {
|
||||
out << ']';
|
||||
}
|
||||
return out << ':' << std::dec << static_cast<int>(endpoint.port);
|
||||
}
|
||||
|
||||
std::string IPEndpoint::ToString() const {
|
||||
std::ostringstream name;
|
||||
name << *this;
|
||||
return name.str();
|
||||
}
|
||||
|
||||
} // namespace openscreen
|
||||
209
breadcast-caststream-sys/vendor/openscreen/platform/base/ip_address.h
vendored
Normal file
209
breadcast-caststream-sys/vendor/openscreen/platform/base/ip_address.h
vendored
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_IP_ADDRESS_H_
|
||||
#define PLATFORM_BASE_IP_ADDRESS_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#include "platform/base/error.h"
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
class IPAddress {
|
||||
public:
|
||||
enum class Version {
|
||||
kV4,
|
||||
kV6,
|
||||
};
|
||||
|
||||
static constexpr IPAddress kAnyV4() { return IPAddress{0, 0, 0, 0}; }
|
||||
static constexpr IPAddress kAnyV6() {
|
||||
return IPAddress{0, 0, 0, 0, 0, 0, 0, 0};
|
||||
}
|
||||
static constexpr IPAddress kV4LoopbackAddress() {
|
||||
return IPAddress{127, 0, 0, 1};
|
||||
}
|
||||
static constexpr IPAddress kV6LoopbackAddress() {
|
||||
return IPAddress{0, 0, 0, 0, 0, 0, 0, 1};
|
||||
}
|
||||
static constexpr size_t kV4Size = 4;
|
||||
static constexpr size_t kV6Size = 16;
|
||||
|
||||
constexpr IPAddress() : version_(Version::kV4), bytes_({}) {}
|
||||
|
||||
// `bytes` contains 4 octets for IPv4, or 8 hextets (16 bytes of big-endian
|
||||
// shorts) for IPv6.
|
||||
// TODO(jophba): delete once usage is removed in Chromium's network_util.cc.
|
||||
inline IPAddress(Version version, const uint8_t* bytes) : version_(version) {
|
||||
std::copy_n(bytes, size(), bytes_.begin());
|
||||
}
|
||||
|
||||
IPAddress(Version version, std::span<const uint8_t> bytes);
|
||||
|
||||
// IPv4 constructors (IPAddress from 4 octets).
|
||||
explicit constexpr IPAddress(std::span<const uint8_t, 4> bytes)
|
||||
: version_(Version::kV4),
|
||||
bytes_{{bytes[0], bytes[1], bytes[2], bytes[3]}} {}
|
||||
|
||||
constexpr IPAddress(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
|
||||
: version_(Version::kV4), bytes_{{b1, b2, b3, b4}} {}
|
||||
|
||||
// IPv6 constructors (IPAddress from 8 hextets).
|
||||
explicit constexpr IPAddress(std::span<const uint16_t, 8> hextets)
|
||||
: IPAddress(hextets[0],
|
||||
hextets[1],
|
||||
hextets[2],
|
||||
hextets[3],
|
||||
hextets[4],
|
||||
hextets[5],
|
||||
hextets[6],
|
||||
hextets[7]) {}
|
||||
|
||||
constexpr IPAddress(uint16_t h0,
|
||||
uint16_t h1,
|
||||
uint16_t h2,
|
||||
uint16_t h3,
|
||||
uint16_t h4,
|
||||
uint16_t h5,
|
||||
uint16_t h6,
|
||||
uint16_t h7)
|
||||
: version_(Version::kV6),
|
||||
bytes_{{
|
||||
static_cast<uint8_t>(h0 >> 8),
|
||||
static_cast<uint8_t>(h0),
|
||||
static_cast<uint8_t>(h1 >> 8),
|
||||
static_cast<uint8_t>(h1),
|
||||
static_cast<uint8_t>(h2 >> 8),
|
||||
static_cast<uint8_t>(h2),
|
||||
static_cast<uint8_t>(h3 >> 8),
|
||||
static_cast<uint8_t>(h3),
|
||||
static_cast<uint8_t>(h4 >> 8),
|
||||
static_cast<uint8_t>(h4),
|
||||
static_cast<uint8_t>(h5 >> 8),
|
||||
static_cast<uint8_t>(h5),
|
||||
static_cast<uint8_t>(h6 >> 8),
|
||||
static_cast<uint8_t>(h6),
|
||||
static_cast<uint8_t>(h7 >> 8),
|
||||
static_cast<uint8_t>(h7),
|
||||
}} {}
|
||||
|
||||
// IPv6 constructor with scope ID.
|
||||
explicit constexpr IPAddress(std::span<const uint8_t, 16> bytes,
|
||||
uint32_t scope_id)
|
||||
: version_(Version::kV6), scope_id_(scope_id) {
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
bytes_[i] = bytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
constexpr IPAddress(const IPAddress& o) noexcept = default;
|
||||
constexpr IPAddress(IPAddress&& o) noexcept = default;
|
||||
~IPAddress() = default;
|
||||
|
||||
constexpr IPAddress& operator=(const IPAddress& o) noexcept = default;
|
||||
constexpr IPAddress& operator=(IPAddress&& o) noexcept = default;
|
||||
|
||||
bool operator==(const IPAddress& o) const;
|
||||
bool operator!=(const IPAddress& o) const;
|
||||
|
||||
// IP address comparison rules are based on the following two principles:
|
||||
// 1. newer versions are greater, e.g. IPv6 > IPv4
|
||||
// 2. higher numerical values are greater, e.g. 192.168.0.1 > 10.0.0.1
|
||||
bool operator<(const IPAddress& other) const;
|
||||
bool operator>(const IPAddress& other) const { return other < *this; }
|
||||
bool operator<=(const IPAddress& other) const { return !(other < *this); }
|
||||
bool operator>=(const IPAddress& other) const { return !(*this < other); }
|
||||
explicit operator bool() const;
|
||||
|
||||
Version version() const { return version_; }
|
||||
size_t size() const { return (version_ == Version::kV4) ? kV4Size : kV6Size; }
|
||||
bool IsV4() const { return version_ == Version::kV4; }
|
||||
bool IsV6() const { return version_ == Version::kV6; }
|
||||
|
||||
// Returns true if the address is an IPv6 link-local address.
|
||||
bool IsLinkLocal() const;
|
||||
|
||||
// Returns the scope ID for link-local IPv6 addresses. Returns 0 for
|
||||
// non-link-local addresses.
|
||||
uint32_t GetScopeId() const { return scope_id_; }
|
||||
|
||||
// These methods assume `x` is the appropriate size, but due to various
|
||||
// callers' casting needs we can't check them like the constructors above.
|
||||
// Callers should instead make any necessary checks themselves.
|
||||
void CopyTo(std::span<uint8_t> bytes) const;
|
||||
|
||||
// TODO(jophba): delete once usage is removed in Chromium's network_util.cc.
|
||||
inline void CopyToV4(uint8_t* x) const { CopyTo(std::span(x, kV4Size)); }
|
||||
inline void CopyToV6(uint8_t* x) const { CopyTo(std::span(x, kV6Size)); }
|
||||
|
||||
// In some instances, we want direct access to the underlying byte storage,
|
||||
// in order to avoid making multiple copies.
|
||||
std::span<const uint8_t> bytes() const {
|
||||
return {bytes_.data(), (version_ == Version::kV4) ? kV4Size : kV6Size};
|
||||
}
|
||||
|
||||
// Parses a text representation of an IPv4 address (e.g. "192.168.0.1") or an
|
||||
// IPv6 address (e.g. "abcd::1234").
|
||||
static ErrorOr<IPAddress> Parse(std::string_view s);
|
||||
|
||||
private:
|
||||
friend ErrorOr<IPAddress> ParseV6(std::string_view s);
|
||||
|
||||
Version version_;
|
||||
std::array<uint8_t, 16> bytes_;
|
||||
uint32_t scope_id_ = 0;
|
||||
};
|
||||
|
||||
struct IPEndpoint {
|
||||
public:
|
||||
IPAddress address;
|
||||
uint16_t port = 0;
|
||||
|
||||
// Used with various socket types to indicate "any" address.
|
||||
static const IPEndpoint kAnyV4();
|
||||
static const IPEndpoint kAnyV6();
|
||||
explicit operator bool() const;
|
||||
|
||||
// Parses a text representation of an IPv4/IPv6 address and port (e.g.
|
||||
// "192.168.0.1:8080" or "[abcd::1234]:8080").
|
||||
static ErrorOr<IPEndpoint> Parse(std::string_view s);
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
bool operator==(const IPEndpoint& a, const IPEndpoint& b);
|
||||
bool operator!=(const IPEndpoint& a, const IPEndpoint& b);
|
||||
|
||||
bool operator<(const IPEndpoint& a, const IPEndpoint& b);
|
||||
inline bool operator>(const IPEndpoint& a, const IPEndpoint& b) {
|
||||
return b < a;
|
||||
}
|
||||
inline bool operator<=(const IPEndpoint& a, const IPEndpoint& b) {
|
||||
return !(a > b);
|
||||
}
|
||||
inline bool operator>=(const IPEndpoint& a, const IPEndpoint& b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
// Outputs a string of the form:
|
||||
// 123.234.34.56
|
||||
// or fe80:0000:0000:0000:1234:5678:9abc:def0
|
||||
std::ostream& operator<<(std::ostream& out, const IPAddress& address);
|
||||
|
||||
// Outputs a string of the form:
|
||||
// 123.234.34.56:443
|
||||
// or [fe80:0000:0000:0000:1234:5678:9abc:def0]:8080
|
||||
std::ostream& operator<<(std::ostream& out, const IPEndpoint& endpoint);
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_IP_ADDRESS_H_
|
||||
54
breadcast-caststream-sys/vendor/openscreen/platform/base/location.cc
vendored
Normal file
54
breadcast-caststream-sys/vendor/openscreen/platform/base/location.cc
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) 2012 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/location.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "platform/base/compiler_specific.h"
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
Location::Location() = default;
|
||||
Location::Location(const Location&) = default;
|
||||
Location::Location(Location&&) noexcept = default;
|
||||
|
||||
Location::Location(const void* program_counter)
|
||||
: program_counter_(program_counter) {}
|
||||
|
||||
Location& Location::operator=(const Location& other) = default;
|
||||
Location& Location::operator=(Location&& other) = default;
|
||||
|
||||
std::string Location::ToString() const {
|
||||
if (program_counter_ == nullptr) {
|
||||
return "pc:nullptr";
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "pc:" << program_counter_;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define RETURN_ADDRESS() \
|
||||
__builtin_extract_return_addr(__builtin_return_address(0))
|
||||
#else
|
||||
#define RETURN_ADDRESS() nullptr
|
||||
#endif
|
||||
|
||||
// static
|
||||
OSP_NOINLINE Location Location::CreateFromHere() {
|
||||
return Location(RETURN_ADDRESS());
|
||||
}
|
||||
|
||||
// static
|
||||
OSP_NOINLINE const void* GetProgramCounter() {
|
||||
return RETURN_ADDRESS();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Location& location) {
|
||||
return out << location.ToString();
|
||||
}
|
||||
|
||||
} // namespace openscreen
|
||||
65
breadcast-caststream-sys/vendor/openscreen/platform/base/location.h
vendored
Normal file
65
breadcast-caststream-sys/vendor/openscreen/platform/base/location.h
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) 2012 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_LOCATION_H_
|
||||
#define PLATFORM_BASE_LOCATION_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
// NOTE: lifted from Chromium's base Location implementation, forked to work
|
||||
// with our base library.
|
||||
|
||||
// Instances of the location class include basic information about a position
|
||||
// in program source, for example the place where an object was constructed.
|
||||
class Location {
|
||||
public:
|
||||
Location();
|
||||
Location(const Location&);
|
||||
Location(Location&&) noexcept;
|
||||
|
||||
// Initializes the program counter
|
||||
explicit Location(const void* program_counter);
|
||||
|
||||
Location& operator=(const Location& other);
|
||||
Location& operator=(Location&& other);
|
||||
|
||||
// Comparator for hash map insertion. The program counter should uniquely
|
||||
// identify a location.
|
||||
bool operator==(const Location& other) const {
|
||||
return program_counter_ == other.program_counter_;
|
||||
}
|
||||
|
||||
// The address of the code generating this Location object. Should always be
|
||||
// valid except for default initialized Location objects, which will be
|
||||
// nullptr.
|
||||
const void* program_counter() const { return program_counter_; }
|
||||
|
||||
// Converts to the most user-readable form possible. This will return
|
||||
// "pc:<hex address>".
|
||||
std::string ToString() const;
|
||||
|
||||
static Location CreateFromHere();
|
||||
|
||||
private:
|
||||
#if defined(__clang__)
|
||||
[[clang::annotate("raw_ptr_exclusion")]]
|
||||
#endif
|
||||
const void* program_counter_ = nullptr;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const Location& location);
|
||||
|
||||
const void* GetProgramCounter();
|
||||
|
||||
#define CURRENT_LOCATION ::openscreen::Location::CreateFromHere()
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_LOCATION_H_
|
||||
39
breadcast-caststream-sys/vendor/openscreen/platform/base/span.h
vendored
Normal file
39
breadcast-caststream-sys/vendor/openscreen/platform/base/span.h
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_SPAN_H_
|
||||
#define PLATFORM_BASE_SPAN_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "platform/base/type_util.h"
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
// In Open Screen code, use these aliases for the most common types of Spans.
|
||||
// TODO(crbug.com/364687926): rename to byte_view.h and remove Span alias.
|
||||
using ByteView = std::span<const uint8_t>;
|
||||
using ByteBuffer = std::span<uint8_t>;
|
||||
template <typename T>
|
||||
using Span = std::span<T>;
|
||||
|
||||
inline ByteView ByteViewFromString(std::string_view str) {
|
||||
return ByteView(reinterpret_cast<const uint8_t*>(str.data()), str.size());
|
||||
}
|
||||
|
||||
inline std::string ByteViewToString(ByteView bytes) {
|
||||
return std::string(reinterpret_cast<const char*>(bytes.data()), bytes.size());
|
||||
}
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_SPAN_H_
|
||||
20
breadcast-caststream-sys/vendor/openscreen/platform/base/tls_connect_options.h
vendored
Normal file
20
breadcast-caststream-sys/vendor/openscreen/platform/base/tls_connect_options.h
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_TLS_CONNECT_OPTIONS_H_
|
||||
#define PLATFORM_BASE_TLS_CONNECT_OPTIONS_H_
|
||||
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
struct TlsConnectOptions {
|
||||
// This option allows TLS connections to devices without
|
||||
// a known hostname, and will typically be “true” for cast code.
|
||||
// For example, the cast_socket always sets true.
|
||||
bool unsafely_skip_certificate_validation;
|
||||
};
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_TLS_CONNECT_OPTIONS_H_
|
||||
22
breadcast-caststream-sys/vendor/openscreen/platform/base/tls_credentials.cc
vendored
Normal file
22
breadcast-caststream-sys/vendor/openscreen/platform/base/tls_credentials.cc
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/tls_credentials.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
TlsCredentials::TlsCredentials() = default;
|
||||
|
||||
TlsCredentials::TlsCredentials(std::vector<uint8_t> der_rsa_private_key,
|
||||
std::vector<uint8_t> der_rsa_public_key,
|
||||
std::vector<uint8_t> der_x509_cert)
|
||||
: der_rsa_private_key(std::move(der_rsa_private_key)),
|
||||
der_rsa_public_key(std::move(der_rsa_public_key)),
|
||||
der_x509_cert(std::move(der_x509_cert)) {}
|
||||
|
||||
TlsCredentials::~TlsCredentials() = default;
|
||||
|
||||
} // namespace openscreen
|
||||
33
breadcast-caststream-sys/vendor/openscreen/platform/base/tls_credentials.h
vendored
Normal file
33
breadcast-caststream-sys/vendor/openscreen/platform/base/tls_credentials.h
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_TLS_CREDENTIALS_H_
|
||||
#define PLATFORM_BASE_TLS_CREDENTIALS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
struct TlsCredentials {
|
||||
TlsCredentials();
|
||||
TlsCredentials(std::vector<uint8_t> der_rsa_private_key,
|
||||
std::vector<uint8_t> der_rsa_public_key,
|
||||
std::vector<uint8_t> der_x509_cert);
|
||||
~TlsCredentials();
|
||||
|
||||
// DER-encoded RSA private key.
|
||||
std::vector<uint8_t> der_rsa_private_key;
|
||||
|
||||
// DER-encoded RSA public key.
|
||||
std::vector<uint8_t> der_rsa_public_key;
|
||||
|
||||
// DER-encoded X509 Certificate that is based on the above keys.
|
||||
std::vector<uint8_t> der_x509_cert;
|
||||
};
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_TLS_CREDENTIALS_H_
|
||||
19
breadcast-caststream-sys/vendor/openscreen/platform/base/tls_listen_options.h
vendored
Normal file
19
breadcast-caststream-sys/vendor/openscreen/platform/base/tls_listen_options.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_TLS_LISTEN_OPTIONS_H_
|
||||
#define PLATFORM_BASE_TLS_LISTEN_OPTIONS_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
struct TlsListenOptions {
|
||||
uint32_t backlog_size;
|
||||
};
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_TLS_LISTEN_OPTIONS_H_
|
||||
72
breadcast-caststream-sys/vendor/openscreen/platform/base/trace_logging_activation.cc
vendored
Normal file
72
breadcast-caststream-sys/vendor/openscreen/platform/base/trace_logging_activation.cc
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/trace_logging_activation.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <thread>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
namespace {
|
||||
|
||||
// If tracing is active, this is a valid pointer to an object that implements
|
||||
// the TraceLoggingPlatform interface. If tracing is not active, this is
|
||||
// nullptr.
|
||||
std::atomic<TraceLoggingPlatform*> g_current_destination{};
|
||||
|
||||
// The count of threads currently calling into the current TraceLoggingPlatform.
|
||||
std::atomic<int> g_use_count{};
|
||||
|
||||
inline TraceLoggingPlatform* PinCurrentDestination() {
|
||||
// NOTE: It's important to increment the global use count *before* loading the
|
||||
// pointer, to ensure the referent is pinned-down (i.e., any thread executing
|
||||
// StopTracing() stays blocked) until CurrentTracingDestination's destructor
|
||||
// calls UnpinCurrentDestination().
|
||||
g_use_count.fetch_add(1);
|
||||
return g_current_destination.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
inline void UnpinCurrentDestination() {
|
||||
g_use_count.fetch_sub(1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void StartTracing(TraceLoggingPlatform* destination) {
|
||||
assert(destination);
|
||||
auto* const old_destination = g_current_destination.exchange(destination);
|
||||
(void)old_destination; // Prevent "unused variable" compiler warnings.
|
||||
assert(old_destination == nullptr || old_destination == destination);
|
||||
}
|
||||
|
||||
void StopTracing() {
|
||||
auto* const old_destination = g_current_destination.exchange(nullptr);
|
||||
if (!old_destination) {
|
||||
return; // Already stopped.
|
||||
}
|
||||
|
||||
// Block the current thread until the global use count goes to zero. At that
|
||||
// point, there can no longer be any dangling references. Theoretically, this
|
||||
// loop may never terminate; but in practice, that should never happen. If it
|
||||
// did happen, that would mean one or more CPU cores are continuously spending
|
||||
// most of their time executing the TraceLoggingPlatform methods, yet those
|
||||
// methods are supposed to be super-cheap and take near-zero time to execute!
|
||||
[[maybe_unused]] int iters = 0;
|
||||
while (g_use_count.load(std::memory_order_relaxed) != 0) {
|
||||
assert(iters < 1024);
|
||||
std::this_thread::yield();
|
||||
++iters;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentTracingDestination::CurrentTracingDestination()
|
||||
: destination_(PinCurrentDestination()) {}
|
||||
|
||||
CurrentTracingDestination::~CurrentTracingDestination() {
|
||||
UnpinCurrentDestination();
|
||||
}
|
||||
|
||||
} // namespace openscreen
|
||||
58
breadcast-caststream-sys/vendor/openscreen/platform/base/trace_logging_activation.h
vendored
Normal file
58
breadcast-caststream-sys/vendor/openscreen/platform/base/trace_logging_activation.h
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_TRACE_LOGGING_ACTIVATION_H_
|
||||
#define PLATFORM_BASE_TRACE_LOGGING_ACTIVATION_H_
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
class TraceLoggingPlatform;
|
||||
|
||||
// Start or Stop trace logging. It is illegal to call StartTracing() a second
|
||||
// time without having called StopTracing() to stop the prior tracing session.
|
||||
//
|
||||
// Note that StopTracing() may block until all threads have returned from any
|
||||
// in-progress calls into the TraceLoggingPlatform's methods.
|
||||
void StartTracing(TraceLoggingPlatform* destination);
|
||||
void StopTracing();
|
||||
|
||||
// An immutable, non-copyable and non-movable smart pointer that references the
|
||||
// current trace logging destination. If tracing was active when this class was
|
||||
// intantiated, the pointer is valid for the life of the instance, and can be
|
||||
// used to directly invoke the methods of the TraceLoggingPlatform API. If
|
||||
// tracing was not active when this class was intantiated, the pointer is null
|
||||
// for the life of the instance and must not be dereferenced.
|
||||
//
|
||||
// An instance should be short-lived, as a platform's call to StopTracing() will
|
||||
// be blocked until there are no instances remaining.
|
||||
//
|
||||
// NOTE: This is generally not used directly, but instead via the
|
||||
// util/trace_logging macros.
|
||||
class CurrentTracingDestination {
|
||||
public:
|
||||
CurrentTracingDestination();
|
||||
~CurrentTracingDestination();
|
||||
|
||||
explicit operator bool() const noexcept { return !!destination_; }
|
||||
TraceLoggingPlatform* operator->() const noexcept { return destination_; }
|
||||
|
||||
private:
|
||||
CurrentTracingDestination(const CurrentTracingDestination&) = delete;
|
||||
CurrentTracingDestination(CurrentTracingDestination&&) noexcept = delete;
|
||||
CurrentTracingDestination& operator=(const CurrentTracingDestination&) =
|
||||
delete;
|
||||
CurrentTracingDestination& operator=(CurrentTracingDestination&&) noexcept =
|
||||
delete;
|
||||
|
||||
// The destination at the time this class was constructed, and is valid for
|
||||
// the lifetime of this class. This is nullptr if tracing was inactive.
|
||||
#if defined(__clang__)
|
||||
[[clang::annotate("raw_ptr_exclusion")]]
|
||||
#endif
|
||||
TraceLoggingPlatform* const destination_;
|
||||
};
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_TRACE_LOGGING_ACTIVATION_H_
|
||||
62
breadcast-caststream-sys/vendor/openscreen/platform/base/trace_logging_types.cc
vendored
Normal file
62
breadcast-caststream-sys/vendor/openscreen/platform/base/trace_logging_types.cc
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2022 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/trace_logging_types.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
std::string TraceIdHierarchy::ToString() const {
|
||||
std::stringstream ss;
|
||||
ss << "[" << std::hex << (HasRoot() ? root : 0) << ":"
|
||||
<< (HasParent() ? parent : 0) << ":" << (HasCurrent() ? current : 0)
|
||||
<< std::dec << "]";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const TraceIdHierarchy& ids) {
|
||||
return out << ids.ToString();
|
||||
}
|
||||
|
||||
bool operator==(const TraceIdHierarchy& lhs, const TraceIdHierarchy& rhs) {
|
||||
return lhs.current == rhs.current && lhs.parent == rhs.parent &&
|
||||
lhs.root == rhs.root;
|
||||
}
|
||||
|
||||
bool operator!=(const TraceIdHierarchy& lhs, const TraceIdHierarchy& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
const char* ToString(TraceCategory category) {
|
||||
switch (category) {
|
||||
case TraceCategory::kAny:
|
||||
return "any";
|
||||
case TraceCategory::kMdns:
|
||||
return "mdns";
|
||||
case TraceCategory::kQuic:
|
||||
return "quic";
|
||||
case TraceCategory::kSsl:
|
||||
return "ssl";
|
||||
case TraceCategory::kPresentation:
|
||||
return "presentation";
|
||||
case TraceCategory::kStandaloneReceiver:
|
||||
return "standalone_receiver";
|
||||
case TraceCategory::kDiscovery:
|
||||
return "discovery";
|
||||
case TraceCategory::kStandaloneSender:
|
||||
return "standalone_sender";
|
||||
case TraceCategory::kReceiver:
|
||||
return "receiver";
|
||||
case TraceCategory::kSender:
|
||||
return "sender";
|
||||
}
|
||||
|
||||
// OSP_NOTREACHED is not available in platform/base.
|
||||
std::abort();
|
||||
}
|
||||
|
||||
} // namespace openscreen
|
||||
71
breadcast-caststream-sys/vendor/openscreen/platform/base/trace_logging_types.h
vendored
Normal file
71
breadcast-caststream-sys/vendor/openscreen/platform/base/trace_logging_types.h
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_TRACE_LOGGING_TYPES_H_
|
||||
#define PLATFORM_BASE_TRACE_LOGGING_TYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
// Define TraceId type here since other TraceLogging files import it.
|
||||
using TraceId = uint64_t;
|
||||
|
||||
// kEmptyTraceId is the Trace ID when tracing at a global level, not inside any
|
||||
// tracing block - ie this will be the parent ID for a top level tracing block.
|
||||
inline constexpr TraceId kEmptyTraceId = 0x0;
|
||||
|
||||
// kUnsetTraceId is the Trace ID passed in to the tracing library when no user-
|
||||
// specified value is desired.
|
||||
inline constexpr TraceId kUnsetTraceId = std::numeric_limits<TraceId>::max();
|
||||
|
||||
// A class to represent the current TraceId Hierarchy and for the user to
|
||||
// pass around as needed.
|
||||
struct TraceIdHierarchy {
|
||||
TraceId current = kUnsetTraceId;
|
||||
TraceId parent = kUnsetTraceId;
|
||||
TraceId root = kUnsetTraceId;
|
||||
|
||||
static constexpr TraceIdHierarchy Empty() {
|
||||
return {kEmptyTraceId, kEmptyTraceId, kEmptyTraceId};
|
||||
}
|
||||
|
||||
bool HasCurrent() const { return current != kUnsetTraceId; }
|
||||
bool HasParent() const { return parent != kUnsetTraceId; }
|
||||
bool HasRoot() const { return root != kUnsetTraceId; }
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const TraceIdHierarchy& ids);
|
||||
|
||||
bool operator==(const TraceIdHierarchy& lhs, const TraceIdHierarchy& rhs);
|
||||
|
||||
bool operator!=(const TraceIdHierarchy& lhs, const TraceIdHierarchy& rhs);
|
||||
|
||||
// Supported trace category
|
||||
enum class TraceCategory : int {
|
||||
kAny,
|
||||
kMdns,
|
||||
kQuic,
|
||||
kSsl,
|
||||
kPresentation,
|
||||
kStandaloneReceiver,
|
||||
kDiscovery,
|
||||
kStandaloneSender,
|
||||
kReceiver,
|
||||
kSender
|
||||
};
|
||||
|
||||
const char* ToString(TraceCategory category);
|
||||
|
||||
enum class FlowType { kFlowBegin, kFlowStep, kFlowEnd };
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_TRACE_LOGGING_TYPES_H_
|
||||
55
breadcast-caststream-sys/vendor/openscreen/platform/base/trivial_clock_traits.cc
vendored
Normal file
55
breadcast-caststream-sys/vendor/openscreen/platform/base/trivial_clock_traits.cc
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/trivial_clock_traits.h"
|
||||
|
||||
namespace openscreen {
|
||||
namespace {
|
||||
|
||||
constexpr char kMicrosecondsUnits[] = " µs";
|
||||
constexpr char kMicrosecondsTicksUnits[] = " µs-ticks";
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string ToString(const TrivialClockTraits::duration& d) {
|
||||
return std::to_string(d.count()) + kMicrosecondsUnits;
|
||||
}
|
||||
|
||||
std::string ToString(const TrivialClockTraits::time_point& tp) {
|
||||
return std::to_string(tp.time_since_epoch().count()) +
|
||||
kMicrosecondsTicksUnits;
|
||||
}
|
||||
|
||||
namespace clock_operators {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
const TrivialClockTraits::duration& d) {
|
||||
return os << d.count() << kMicrosecondsUnits;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
const TrivialClockTraits::time_point& tp) {
|
||||
return os << tp.time_since_epoch().count() << kMicrosecondsTicksUnits;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::hours& hrs) {
|
||||
return (os << hrs.count() << " hours");
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::minutes& mins) {
|
||||
return (os << mins.count() << " minutes");
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::seconds& secs) {
|
||||
return (os << secs.count() << " seconds");
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
const std::chrono::milliseconds& millis) {
|
||||
return (os << millis.count() << " ms");
|
||||
}
|
||||
|
||||
} // namespace clock_operators
|
||||
|
||||
} // namespace openscreen
|
||||
98
breadcast-caststream-sys/vendor/openscreen/platform/base/trivial_clock_traits.h
vendored
Normal file
98
breadcast-caststream-sys/vendor/openscreen/platform/base/trivial_clock_traits.h
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_TRIVIAL_CLOCK_TRAITS_H_
|
||||
#define PLATFORM_BASE_TRIVIAL_CLOCK_TRAITS_H_
|
||||
|
||||
#include <chrono>
|
||||
#include <ostream>
|
||||
#include <ratio>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
// The Open Screen monotonic clock traits description, providing all the C++14
|
||||
// requirements of a TrivialClock, for use with STL <chrono>.
|
||||
class TrivialClockTraits {
|
||||
public:
|
||||
// TrivialClock named requirements: std::chrono templates can/may use these.
|
||||
// NOTE: unless you are specifically integrating with the clock, you probably
|
||||
// don't want to use these types, and instead should reference the std::chrono
|
||||
// types directly.
|
||||
using duration = std::chrono::microseconds;
|
||||
using rep = duration::rep;
|
||||
using period = duration::period;
|
||||
using time_point = std::chrono::time_point<TrivialClockTraits, duration>;
|
||||
static constexpr bool is_steady = true;
|
||||
|
||||
// Helper method for named requirements.
|
||||
template <typename D>
|
||||
static constexpr duration to_duration(D d) {
|
||||
return std::chrono::duration_cast<duration>(d);
|
||||
}
|
||||
|
||||
// Time point values from the clock use microsecond precision, as a reasonably
|
||||
// high-resolution clock is required. The time source must tick forward at
|
||||
// least 10000 times per second.
|
||||
using kRequiredResolution = std::ratio<1, 10000>;
|
||||
|
||||
// In <chrono>, a clock type is just some type properties plus a static now()
|
||||
// function. So, there's nothing to instantiate here.
|
||||
TrivialClockTraits() = delete;
|
||||
~TrivialClockTraits() = delete;
|
||||
|
||||
// "Trivially copyable" is necessary for using the time types in
|
||||
// std::atomic<>.
|
||||
static_assert(std::is_trivially_copyable<duration>(),
|
||||
"duration is not trivially copyable");
|
||||
static_assert(std::is_trivially_copyable<time_point>(),
|
||||
"time_point is not trivially copyable");
|
||||
};
|
||||
|
||||
// Convenience type definition, for injecting time sources into classes (e.g.,
|
||||
// &Clock::now versus something else for testing).
|
||||
using ClockNowFunctionPtr = TrivialClockTraits::time_point (*)();
|
||||
|
||||
// Convenience for serializing to string, e.g. for tracing. Outputs a string of
|
||||
// the form "123µs".
|
||||
std::string ToString(const TrivialClockTraits::duration& d);
|
||||
|
||||
// Convenience for serializing to string, e.g. for tracing. Outputs a string of
|
||||
// the form "123µs-ticks".
|
||||
std::string ToString(const TrivialClockTraits::time_point& tp);
|
||||
|
||||
// Explicit namespace for inclusion of custom time-related operator<<
|
||||
// implementations. These operators may be included in a file for use by adding:
|
||||
// using clock_operators::operator<<;
|
||||
//
|
||||
// NOTE: in some cases, resolution of these operators may still fail, most
|
||||
// notably in Google Test/Mock when attempting to serialize to an EXPECT_*
|
||||
// or ASSERT_* call. In this case, the manual "ToString" functions above must
|
||||
// be called instead.
|
||||
namespace clock_operators {
|
||||
|
||||
// Logging convenience for durations. Outputs a string of the form "123µs".
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
const TrivialClockTraits::duration& d);
|
||||
|
||||
// Logging convenience for time points. Outputs a string of the form
|
||||
// "123µs-ticks".
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
const TrivialClockTraits::time_point& tp);
|
||||
|
||||
// Logging (and gtest pretty-printing) for several commonly-used chrono types.
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::hours&);
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::minutes&);
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::seconds&);
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::milliseconds&);
|
||||
std::ostream& operator<<(std::ostream& os, const std::chrono::microseconds& d);
|
||||
// Note: The ostream output operator for std::chrono::microseconds is handled by
|
||||
// the one for TrivialClockTraits::duration above since they are the same type.
|
||||
|
||||
} // namespace clock_operators
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_TRIVIAL_CLOCK_TRAITS_H_
|
||||
24
breadcast-caststream-sys/vendor/openscreen/platform/base/type_util.h
vendored
Normal file
24
breadcast-caststream-sys/vendor/openscreen/platform/base/type_util.h
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_TYPE_UTIL_H_
|
||||
#define PLATFORM_BASE_TYPE_UTIL_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// File for defining generally useful type predicates for templatized classes
|
||||
// and functions.
|
||||
namespace openscreen::internal {
|
||||
|
||||
template <typename T>
|
||||
using EnableIfArithmetic =
|
||||
std::enable_if_t<std::is_arithmetic<T>::value>; // NOLINT
|
||||
|
||||
template <typename From, typename To>
|
||||
using EnableIfConvertible = std::enable_if_t<
|
||||
std::is_convertible<From (*)[], To (*)[]>::value>; // NOLINT
|
||||
|
||||
} // namespace openscreen::internal
|
||||
|
||||
#endif // PLATFORM_BASE_TYPE_UTIL_H_
|
||||
30
breadcast-caststream-sys/vendor/openscreen/platform/base/udp_packet.cc
vendored
Normal file
30
breadcast-caststream-sys/vendor/openscreen/platform/base/udp_packet.cc
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "platform/base/udp_packet.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
UdpPacket::UdpPacket() : std::vector<uint8_t>() {}
|
||||
|
||||
UdpPacket::UdpPacket(size_type size, uint8_t fill_value)
|
||||
: std::vector<uint8_t>(size, fill_value) {
|
||||
assert(size <= kUdpMaxPacketSize);
|
||||
}
|
||||
|
||||
UdpPacket::UdpPacket(UdpPacket&& other) noexcept = default;
|
||||
|
||||
UdpPacket::UdpPacket(std::initializer_list<uint8_t> init)
|
||||
: std::vector<uint8_t>(init) {
|
||||
assert(size() <= kUdpMaxPacketSize);
|
||||
}
|
||||
|
||||
UdpPacket::~UdpPacket() = default;
|
||||
|
||||
UdpPacket& UdpPacket::operator=(UdpPacket&& other) = default;
|
||||
|
||||
} // namespace openscreen
|
||||
54
breadcast-caststream-sys/vendor/openscreen/platform/base/udp_packet.h
vendored
Normal file
54
breadcast-caststream-sys/vendor/openscreen/platform/base/udp_packet.h
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef PLATFORM_BASE_UDP_PACKET_H_
|
||||
#define PLATFORM_BASE_UDP_PACKET_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "platform/base/ip_address.h"
|
||||
|
||||
namespace openscreen {
|
||||
|
||||
// A move-only std::vector of bytes that may not exceed the maximum possible
|
||||
// size of a UDP packet. Implicit copy construction/assignment is disabled to
|
||||
// prevent hidden copies (i.e., those not explicitly coded).
|
||||
class UdpPacket : public std::vector<uint8_t> {
|
||||
public:
|
||||
// C++14 vector constructors, sans Allocator foo, and no copy ctor.
|
||||
UdpPacket();
|
||||
explicit UdpPacket(size_type size, uint8_t fill_value = {});
|
||||
template <typename InputIt>
|
||||
UdpPacket(InputIt first, InputIt last) : std::vector<uint8_t>(first, last) {}
|
||||
UdpPacket(std::initializer_list<uint8_t> init);
|
||||
UdpPacket(const UdpPacket&) = delete;
|
||||
UdpPacket(UdpPacket&& other) noexcept;
|
||||
|
||||
~UdpPacket();
|
||||
|
||||
UdpPacket& operator=(UdpPacket&& other);
|
||||
UdpPacket& operator=(const UdpPacket&) = delete;
|
||||
|
||||
const IPEndpoint& source() const { return source_; }
|
||||
void set_source(IPEndpoint endpoint) { source_ = std::move(endpoint); }
|
||||
|
||||
const IPEndpoint& destination() const { return destination_; }
|
||||
void set_destination(IPEndpoint endpoint) {
|
||||
destination_ = std::move(endpoint);
|
||||
}
|
||||
|
||||
static constexpr size_type kUdpMaxPacketSize = 1 << 16;
|
||||
|
||||
private:
|
||||
IPEndpoint source_ = {};
|
||||
IPEndpoint destination_ = {};
|
||||
};
|
||||
|
||||
} // namespace openscreen
|
||||
|
||||
#endif // PLATFORM_BASE_UDP_PACKET_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue