|
@@ -44,17 +44,25 @@ namespace Google.Protobuf.WellKnownTypes
|
|
|
prefix.EndsWith("/") ? prefix + descriptor.FullName : prefix + "/" + descriptor.FullName;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Retrieves the type name for a type URL. This is always just the last part of the URL,
|
|
|
- /// after the trailing slash. No validation of anything before the trailing slash is performed.
|
|
|
- /// If the type URL does not include a slash, an empty string is returned rather than an exception
|
|
|
- /// being thrown; this won't match any types, and the calling code is probably in a better position
|
|
|
- /// to give a meaningful error.
|
|
|
- /// There is no handling of fragments or queries at the moment.
|
|
|
+ /// Retrieves the type name for a type URL, matching the <see cref="DescriptorBase.FullName"/>
|
|
|
+ /// of the packed message type.
|
|
|
/// </summary>
|
|
|
+ /// <remarks>
|
|
|
+ /// <para>
|
|
|
+ /// This is always just the last part of the URL, after the final slash. No validation of
|
|
|
+ /// anything before the trailing slash is performed. If the type URL does not include a slash,
|
|
|
+ /// an empty string is returned rather than an exception being thrown; this won't match any types,
|
|
|
+ /// and the calling code is probably in a better position to give a meaningful error.
|
|
|
+ /// </para>
|
|
|
+ /// <para>
|
|
|
+ /// There is no handling of fragments or queries at the moment.
|
|
|
+ /// </para>
|
|
|
+ /// </remarks>
|
|
|
/// <param name="typeUrl">The URL to extract the type name from</param>
|
|
|
/// <returns>The type name</returns>
|
|
|
- internal static string GetTypeName(string typeUrl)
|
|
|
+ public static string GetTypeName(string typeUrl)
|
|
|
{
|
|
|
+ ProtoPreconditions.CheckNotNull(typeUrl, nameof(typeUrl));
|
|
|
int lastSlash = typeUrl.LastIndexOf('/');
|
|
|
return lastSlash == -1 ? "" : typeUrl.Substring(lastSlash + 1);
|
|
|
}
|
|
@@ -80,6 +88,27 @@ namespace Google.Protobuf.WellKnownTypes
|
|
|
return target;
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Attempts to unpack the content of this Any message into the target message type,
|
|
|
+ /// if it matches the type URL within this Any message.
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T">The type of message to attempt to unpack the content into.</typeparam>
|
|
|
+ /// <returns><c>true</c> if the message was successfully unpacked; <c>false</c> if the type name didn't match</returns>
|
|
|
+ public bool TryUnpack<T>(out T result) where T : IMessage, new()
|
|
|
+ {
|
|
|
+ // Note: deliberately avoid writing anything to result until the end, in case it's being
|
|
|
+ // monitored by other threads. (That would be a bug in the calling code, but let's not make it worse.)
|
|
|
+ T target = new T();
|
|
|
+ if (GetTypeName(TypeUrl) != target.Descriptor.FullName)
|
|
|
+ {
|
|
|
+ result = default(T); // Can't use null as there's no class constraint, but this always *will* be null in real usage.
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ target.MergeFrom(Value);
|
|
|
+ result = target;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Packs the specified message into an Any message using a type URL prefix of "type.googleapis.com".
|
|
|
/// </summary>
|