"Fossies" - the Fresh Open Source Software Archive

Member "protobuf-3.12.3/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs" (2 Jun 2020, 7531 Bytes) of package /linux/misc/protobuf-all-3.12.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C# source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "AnyPartial.cs" see the Fossies "Dox" file reference documentation.

    1 #region Copyright notice and license
    2 // Protocol Buffers - Google's data interchange format
    3 // Copyright 2015 Google Inc.  All rights reserved.
    4 // https://developers.google.com/protocol-buffers/
    5 //
    6 // Redistribution and use in source and binary forms, with or without
    7 // modification, are permitted provided that the following conditions are
    8 // met:
    9 //
   10 //     * Redistributions of source code must retain the above copyright
   11 // notice, this list of conditions and the following disclaimer.
   12 //     * Redistributions in binary form must reproduce the above
   13 // copyright notice, this list of conditions and the following disclaimer
   14 // in the documentation and/or other materials provided with the
   15 // distribution.
   16 //     * Neither the name of Google Inc. nor the names of its
   17 // contributors may be used to endorse or promote products derived from
   18 // this software without specific prior written permission.
   19 //
   20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31 #endregion
   32 
   33 using Google.Protobuf.Reflection;
   34 
   35 namespace Google.Protobuf.WellKnownTypes
   36 {
   37     public partial class Any
   38     {
   39         private const string DefaultPrefix = "type.googleapis.com";
   40 
   41         // This could be moved to MessageDescriptor if we wanted to, but keeping it here means
   42         // all the Any-specific code is in the same place.
   43         private static string GetTypeUrl(MessageDescriptor descriptor, string prefix) =>
   44             prefix.EndsWith("/") ? prefix + descriptor.FullName : prefix + "/" + descriptor.FullName;
   45 
   46         /// <summary>
   47         /// Retrieves the type name for a type URL, matching the <see cref="DescriptorBase.FullName"/>
   48         /// of the packed message type.
   49         /// </summary>
   50         /// <remarks>
   51         /// <para>
   52         /// This is always just the last part of the URL, after the final slash. No validation of
   53         /// anything before the trailing slash is performed. If the type URL does not include a slash,
   54         /// an empty string is returned rather than an exception being thrown; this won't match any types,
   55         /// and the calling code is probably in a better position to give a meaningful error.
   56         /// </para>
   57         /// <para>
   58         /// There is no handling of fragments or queries  at the moment.
   59         /// </para>
   60         /// </remarks>
   61         /// <param name="typeUrl">The URL to extract the type name from</param>
   62         /// <returns>The type name</returns>
   63         public static string GetTypeName(string typeUrl)
   64         {
   65             ProtoPreconditions.CheckNotNull(typeUrl, nameof(typeUrl));
   66             int lastSlash = typeUrl.LastIndexOf('/');
   67             return lastSlash == -1 ? "" : typeUrl.Substring(lastSlash + 1);
   68         }
   69 
   70         /// <summary>
   71         /// Returns a bool indictating whether this Any message is of the target message type
   72         /// </summary>
   73         /// <param name="descriptor">The descriptor of the message type</param>
   74         /// <returns><c>true</c> if the type name matches the descriptor's full name or <c>false</c> otherwise</returns>
   75         public bool Is(MessageDescriptor descriptor)
   76         {
   77             ProtoPreconditions.CheckNotNull(descriptor, nameof(descriptor));
   78             return GetTypeName(TypeUrl) == descriptor.FullName;
   79         }
   80 
   81         /// <summary>
   82         /// Unpacks the content of this Any message into the target message type,
   83         /// which must match the type URL within this Any message.
   84         /// </summary>
   85         /// <typeparam name="T">The type of message to unpack the content into.</typeparam>
   86         /// <returns>The unpacked message.</returns>
   87         /// <exception cref="InvalidProtocolBufferException">The target message type doesn't match the type URL in this message</exception>
   88         public T Unpack<T>() where T : IMessage, new()
   89         {
   90             // Note: this doesn't perform as well is it might. We could take a MessageParser<T> in an alternative overload,
   91             // which would be expected to perform slightly better... although the difference is likely to be negligible.
   92             T target = new T();
   93             if (GetTypeName(TypeUrl) != target.Descriptor.FullName)
   94             {
   95                 throw new InvalidProtocolBufferException(
   96                     $"Full type name for {target.Descriptor.Name} is {target.Descriptor.FullName}; Any message's type url is {TypeUrl}");
   97             }
   98             target.MergeFrom(Value);
   99             return target;
  100         }
  101 
  102         /// <summary>
  103         /// Attempts to unpack the content of this Any message into the target message type,
  104         /// if it matches the type URL within this Any message.
  105         /// </summary>
  106         /// <typeparam name="T">The type of message to attempt to unpack the content into.</typeparam>
  107         /// <returns><c>true</c> if the message was successfully unpacked; <c>false</c> if the type name didn't match</returns>
  108         public bool TryUnpack<T>(out T result) where T : IMessage, new()
  109         {
  110             // Note: deliberately avoid writing anything to result until the end, in case it's being
  111             // monitored by other threads. (That would be a bug in the calling code, but let's not make it worse.)
  112             T target = new T();
  113             if (GetTypeName(TypeUrl) != target.Descriptor.FullName)
  114             {
  115                 result = default(T); // Can't use null as there's no class constraint, but this always *will* be null in real usage.
  116                 return false;
  117             }
  118             target.MergeFrom(Value);
  119             result = target;
  120             return true;
  121         }
  122 
  123         /// <summary>
  124         /// Packs the specified message into an Any message using a type URL prefix of "type.googleapis.com".
  125         /// </summary>
  126         /// <param name="message">The message to pack.</param>
  127         /// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
  128         public static Any Pack(IMessage message) => Pack(message, DefaultPrefix);
  129 
  130         /// <summary>
  131         /// Packs the specified message into an Any message using the specified type URL prefix.
  132         /// </summary>
  133         /// <param name="message">The message to pack.</param>
  134         /// <param name="typeUrlPrefix">The prefix for the type URL.</param>
  135         /// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
  136         public static Any Pack(IMessage message, string typeUrlPrefix)
  137         {
  138             ProtoPreconditions.CheckNotNull(message, nameof(message));
  139             ProtoPreconditions.CheckNotNull(typeUrlPrefix, nameof(typeUrlPrefix));
  140             return new Any
  141             {
  142                 TypeUrl = GetTypeUrl(message.Descriptor, typeUrlPrefix),
  143                 Value = message.ToByteString()
  144             };
  145         }
  146     }
  147 }