QGrpc{Call,Channel}Options: make addMetadata(QBA, QBA) non-owning

Decouples our public API from the implementation. This is also slightly
superior as potential duplicates will not be copied on function call.

Discovered during the 6.10 API review.

Pick-to: 6.10
Change-Id: I78bc123cf4db034ce12f62a5a4576c8e0d0d64f3
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Dennis Oberst 2025-06-17 13:58:14 +02:00
parent 74bf4bb33e
commit 6670aafd85
7 changed files with 20 additions and 8 deletions

View File

@ -262,13 +262,13 @@ QGrpcCallOptions::setMetadata(std::initializer_list<std::pair<QByteArray, QByteA
\include qgrpccalloptions.cpp merge-md-note
\l{QGrpcChannelOptions::addMetadata()}
*/
QGrpcCallOptions &QGrpcCallOptions::addMetadata(QByteArray key, QByteArray value)
QGrpcCallOptions &QGrpcCallOptions::addMetadata(QByteArrayView key, QByteArrayView value)
{
if (d_ptr->metadata(QtGrpc::MultiValue).contains(key, value))
if (d_ptr->containsMetadata(key, value))
return *this;
d_ptr.detach();
Q_D(QGrpcCallOptions);
d->addMetadata(std::move(key), std::move(value));
d->addMetadata(key.toByteArray(), value.toByteArray());
return *this;
}

View File

@ -62,7 +62,7 @@ public:
Q_GRPC_EXPORT QGrpcCallOptions &setMetadata(QMultiHash<QByteArray, QByteArray> &&metadata);
Q_GRPC_EXPORT QGrpcCallOptions &
setMetadata(std::initializer_list<std::pair<QByteArray, QByteArray>> list);
Q_GRPC_EXPORT QGrpcCallOptions &addMetadata(QByteArray key, QByteArray value);
Q_GRPC_EXPORT QGrpcCallOptions &addMetadata(QByteArrayView key, QByteArrayView value);
private:
QExplicitlySharedDataPointer<QGrpcCallOptionsPrivate> d_ptr;

View File

@ -271,13 +271,13 @@ QGrpcChannelOptions::setMetadata(std::initializer_list<std::pair<QByteArray, QBy
\include qgrpcchanneloptions.cpp merge-md-note
\l{QGrpcCallOptions::addMetadata()}
*/
QGrpcChannelOptions &QGrpcChannelOptions::addMetadata(QByteArray key, QByteArray value)
QGrpcChannelOptions &QGrpcChannelOptions::addMetadata(QByteArrayView key, QByteArrayView value)
{
if (d_ptr->metadata(QtGrpc::MultiValue).contains(key, value))
if (d_ptr->containsMetadata(key, value))
return *this;
d_ptr.detach();
Q_D(QGrpcChannelOptions);
d->addMetadata(std::move(key), std::move(value));
d->addMetadata(key.toByteArray(), value.toByteArray());
return *this;
}

View File

@ -68,7 +68,7 @@ public:
Q_GRPC_EXPORT QGrpcChannelOptions &setMetadata(QMultiHash<QByteArray, QByteArray> &&metadata);
Q_GRPC_EXPORT QGrpcChannelOptions &
setMetadata(std::initializer_list<std::pair<QByteArray, QByteArray>> list);
Q_GRPC_EXPORT QGrpcChannelOptions &addMetadata(QByteArray key, QByteArray value);
Q_GRPC_EXPORT QGrpcChannelOptions &addMetadata(QByteArrayView key, QByteArrayView value);
[[nodiscard]] Q_GRPC_EXPORT QGrpcSerializationFormat serializationFormat() const;
Q_GRPC_EXPORT QGrpcChannelOptions &

View File

@ -165,4 +165,11 @@ void QGrpcCommonOptions::addMetadata(QByteArray &&key, QByteArray &&value)
m_metadataMulti.emplace(std::move(key), std::move(value));
}
bool QGrpcCommonOptions::containsMetadata(QByteArrayView key, QByteArrayView value) const
{
const auto &md = metadata(QtGrpc::MultiValue);
auto [f, l] = md.equal_range(key);
return std::find(f, l, value) != l;
}
QT_END_NAMESPACE

View File

@ -47,6 +47,7 @@ public:
void setMetadata(const QMultiHash<QByteArray, QByteArray> &md);
void setMetadata(QMultiHash<QByteArray, QByteArray> &&md);
void addMetadata(QByteArray &&key, QByteArray &&value);
bool containsMetadata(QByteArrayView key, QByteArrayView value) const;
private:
std::optional<std::chrono::milliseconds> m_timeout;

View File

@ -216,6 +216,10 @@ QT_WARNING_POP
auto o5Detach = o5;
QByteArray k = "keyB", v = "valB";
o5.addMetadata(k, v);
// Check that exact key-value pairs are discarded no matter the order.
o5.addMetadata("keyA", "valA1");
o5.addMetadata("keyA", "valA2");
o5.addMetadata("keyB", "valB");
QCOMPARE_EQ(o5.metadata(QtGrpc::MultiValue), data);
QCOMPARE_NE(o5.metadata(QtGrpc::MultiValue), o5Detach.metadata(QtGrpc::MultiValue));
}