object IDictionary.this[object key] { get { ProtoPreconditions.CheckNotNull <object>(key, nameof(key)); if (!(key is TKey)) { return((object)null); } TValue obj; this.TryGetValue((TKey)key, out obj); return((object)obj); } set { this[(TKey)key] = (TValue)value; } }
/// <summary> /// Adds all of the specified values into this collection. /// </summary> /// <param name="values">The values to add to this collection.</param> public new void AddRange(IEnumerable <T> values) { ProtoPreconditions.CheckNotNull(values, "values"); // Optimization 1: If the collection we're adding is already a RepeatedField<T>, // we know the values are valid. var otherRepeatedField = values as RepeatedField <T>; if (otherRepeatedField != null) { base.AddRange(values); return; } // Optimization 2: The collection is an ICollection, so we can expand // just once and ask the collection to copy itself into the array. var collection = values as ICollection; if (collection != null) { // For reference types and nullable value types, we need to check that there are no nulls // present. (This isn't a thread-safe approach, but we don't advertise this is thread-safe.) // We expect the JITter to optimize this test to true/false, so it's effectively conditional // specialization. if (default(T) == null) { // TODO: Measure whether iterating once to check and then letting the collection copy // itself is faster or slower than iterating and adding as we go. For large // collections this will not be great in terms of cache usage... but the optimized // copy may be significantly faster than doing it one at a time. foreach (var item in collection) { if (item == null) { throw new ArgumentException("Sequence contained null element", "values"); } } } base.AddRange(values); return; } // We *could* check for ICollection<T> as well, but very very few collections implement // ICollection<T> but not ICollection. (HashSet<T> does, for one...) // Fall back to a slower path of adding items one at a time. foreach (T item in values) { Add(item); } }
/// <summary> /// Formats the specified message as text. /// </summary> /// <param name="message">The message to format.</param> /// <param name="writer">The TextWriter to write the formatted message to.</param> /// <returns>The formatted message.</returns> public void Format(IMessage message, TextWriter writer) { ProtoPreconditions.CheckNotNull(message, nameof(message)); ProtoPreconditions.CheckNotNull(writer, nameof(writer)); if (message.Descriptor.IsWellKnownType()) { WriteWellKnownTypeValue(writer, message.Descriptor, message); } else { WriteMessage(writer, message); } }
/// <summary> /// Merge from another MapField /// </summary> /// <param name="other">MapField to merge from</param> public void MergeFrom(MapField <TKey, TValue> other) { ProtoPreconditions.CheckNotNull(other, nameof(other)); foreach (var item in other) { var cloneable = item.Value as IDeepCloneable <TValue>; if (cloneable != null) { this[item.Key] = cloneable.Clone(); } else { this[item.Key] = item.Value; } } }
/// <summary> /// Merge from another RepeatedField /// </summary> /// <param name="other">RepeatedField to merge from</param> public void MergeFrom(RepeatedField <T> other) { ProtoPreconditions.CheckNotNull(other, nameof(other)); EnsureSize(Count + other.Count); foreach (var item in other) { var cloneable = item as IDeepCloneable <T>; if (cloneable != null) { array[count++] = cloneable.Clone(); } else { array[count++] = item; } } }
/// <summary> /// Serializes the <paramref name="message"/> returns the hash of it. /// </summary> /// <param name="provider">The hash provider.</param> /// <param name="message">The protocol message.</param> /// <returns></returns> public static MultiHash ComputeMultiHash(this IHashProvider provider, IMessage message) { ProtoPreconditions.CheckNotNull(message, nameof(message)); var required = message.CalculateSize(); var array = ArrayPool <byte> .Shared.Rent(required); using (var output = new CodedOutputStream(array)) { message.WriteTo(output); } var result = provider.ComputeMultiHash(array, 0, required); ArrayPool <byte> .Shared.Return(array); return(result); }
object IDictionary.this[object key] { get { ProtoPreconditions.CheckNotNull(key, nameof(key)); if (!(key is TKey)) { return(null); } TValue value; TryGetValue((TKey)key, out value); return(value); } set { this[(TKey)key] = (TValue)value; } }
public static bool Verify(this ICryptoContext crypto, ISignature signature, IMessage message, IMessage context) { ProtoPreconditions.CheckNotNull(message, nameof(message)); ProtoPreconditions.CheckNotNull(context, nameof(context)); var messageSize = message.CalculateSize(); var contextSize = context.CalculateSize(); var array = ArrayPool <byte> .Shared.Rent(messageSize + contextSize); using (var output = new CodedOutputStream(array)) { message.WriteTo(output); context.WriteTo(output); } var result = crypto.Verify(signature, array.AsSpan(0, messageSize), array.AsSpan(messageSize, contextSize)); ArrayPool <byte> .Shared.Return(array); return(result); }
/// <summary> /// Converts the given descriptor binary data into FileDescriptor objects. /// Note: reflection using the returned FileDescriptors is not currently supported. /// </summary> /// <param name="descriptorData">The binary file descriptor proto data. Must not be null, and any /// dependencies must come before the descriptor which depends on them. (If A depends on B, and B /// depends on C, then the descriptors must be presented in the order C, B, A.) This is compatible /// with the order in which protoc provides descriptors to plugins.</param> /// <returns>The file descriptors corresponding to <paramref name="descriptorData"/>.</returns> public static ReadOnlyCollection <FileDescriptor> BuildFromByteStrings(IEnumerable <ByteString> descriptorData) { ProtoPreconditions.CheckNotNull(descriptorData, "descriptorData"); // TODO: See if we can build a single DescriptorPool instead of building lots of them. // This will all behave correctly, but it's less efficient than we'd like. var descriptors = new List <FileDescriptor>(); var descriptorsByName = new Dictionary <string, FileDescriptor>(); foreach (var data in descriptorData) { var proto = FileDescriptorProto.Parser.ParseFrom(data); var dependencies = new List <FileDescriptor>(); foreach (var dependencyName in proto.Dependency) { FileDescriptor dependency; if (!descriptorsByName.TryGetValue(dependencyName, out dependency)) { throw new ArgumentException( string.Format("Dependency missing: {0}", dependencyName) ); } dependencies.Add(dependency); } var pool = new DescriptorPool(dependencies); FileDescriptor descriptor = new FileDescriptor( data, proto, dependencies, pool, allowUnknownDependencies: false, generatedCodeInfo: null); descriptor.CrossLink(); descriptors.Add(descriptor); if (descriptorsByName.ContainsKey(descriptor.Name)) { throw new ArgumentException( string.Format("Duplicate descriptor name: {0}", descriptor.Name) ); } descriptorsByName.Add(descriptor.Name, descriptor); } return(new ReadOnlyCollection <FileDescriptor>(descriptors)); }
/// <summary> /// Constructs a new attribute instance for the given name. /// </summary> /// <param name="name">The name of the element in the .proto file.</param> public OriginalNameAttribute(string name) { Name = ProtoPreconditions.CheckNotNull(name, "name"); }
/// <summary> /// Creates a type registry from the file descriptor parents of the specified set of message descriptors. /// </summary> /// <remarks> /// The specified message descriptors are only used to identify their file descriptors; the returned registry /// contains all the types within the file descriptors which contain the specified message descriptors (and /// the dependencies of those files), not just the specified messages. /// </remarks> /// <param name="messageDescriptors">The set of message descriptors to use to identify file descriptors to include in the registry. /// Must not contain null values.</param> /// <returns>A type registry for the given files.</returns> public static TypeRegistry FromMessages(IEnumerable <MessageDescriptor> messageDescriptors) { ProtoPreconditions.CheckNotNull(messageDescriptors, "messageDescriptors"); return(FromFiles(messageDescriptors.Select(md => md.File))); }
/// <summary> /// Returns a bool indictating whether this Any message is of the target message type /// </summary> /// <param name="descriptor">The descriptor of the message type</param> /// <returns><c>true</c> if the type name matches the descriptor's full name or <c>false</c> otherwise</returns> public bool Is(MessageDescriptor descriptor) { ProtoPreconditions.CheckNotNull(descriptor, nameof(descriptor)); return(GetTypeName(TypeUrl) == descriptor.FullName); }
/// <summary> /// Converts a message to text for diagnostic purposes with no extra context. /// </summary> /// <remarks> /// <para> /// This differs from calling <see cref="Format(IMessage)"/> on the default text /// formatter in its handling of <see cref="Any"/>. As no type registry is available /// in <see cref="object.ToString"/> calls, the normal way of resolving the type of /// an <c>Any</c> message cannot be applied. Instead, a text property named <c>@value</c> /// is included with the base64 data from the <see cref="Any.Value"/> property of the message. /// </para> /// <para>The value returned by this method is only designed to be used for diagnostic /// purposes. It may not be parsable by <see cref="TextParser"/>, and may not be parsable /// by other Protocol Buffer implementations.</para> /// </remarks> /// <param name="message">The message to format for diagnostic purposes.</param> /// <returns>The diagnostic-only text representation of the message</returns> public static string ToDiagnosticString(IMessage message) { ProtoPreconditions.CheckNotNull(message, nameof(message)); return(diagnosticFormatter.Format(message)); }
private Settings(int recursionLimit, TypeRegistry typeRegistry, bool ignoreUnknownFields) { RecursionLimit = recursionLimit; TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry)); IgnoreUnknownFields = ignoreUnknownFields; }
/// <summary> /// Constructs a new attribute instance for the given name. /// </summary> /// <param name="name">The name of the element in the .proto file.</param> public OriginalNameAttribute(string name) { Name = ProtoPreconditions.CheckNotNull(name, nameof(name)); PreferredAlias = true; }
/// <summary> /// Determines whether this instance is empty. /// </summary> /// <param name="message">The message.</param> /// <returns> /// <c>true</c> if the specified message is empty; otherwise, <c>false</c>. /// </returns> public static bool IsEmpty(this IMessage message) { ProtoPreconditions.CheckNotNull(message, nameof(message)); return(message.CalculateSize() == 0); }