diff options
Diffstat (limited to 'csharp/src/Google.Protobuf/Collections')
-rw-r--r-- | csharp/src/Google.Protobuf/Collections/MapField.cs | 141 | ||||
-rw-r--r-- | csharp/src/Google.Protobuf/Collections/RepeatedField.cs | 111 |
2 files changed, 246 insertions, 6 deletions
diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs index fc94fd5c..fed3d062 100644 --- a/csharp/src/Google.Protobuf/Collections/MapField.cs +++ b/csharp/src/Google.Protobuf/Collections/MapField.cs @@ -42,14 +42,14 @@ namespace Google.Protobuf.Collections /// <summary> /// Representation of a map field in a Protocol Buffer message. /// </summary> + /// <typeparam name="TKey">Key type in the map. Must be a type supported by Protocol Buffer map keys.</typeparam> + /// <typeparam name="TValue">Value type in the map. Must be a type supported by Protocol Buffers.</typeparam> /// <remarks> /// This implementation preserves insertion order for simplicity of testing /// code using maps fields. Overwriting an existing entry does not change the /// position of that entry within the map. Equality is not order-sensitive. - /// For string keys, the equality comparison is provided by <see cref="StringComparer.Ordinal"/>. + /// For string keys, the equality comparison is provided by <see cref="StringComparer.Ordinal" />. /// </remarks> - /// <typeparam name="TKey">Key type in the map. Must be a type supported by Protocol Buffer map keys.</typeparam> - /// <typeparam name="TValue">Value type in the map. Must be a type supported by Protocol Buffers.</typeparam> public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary { // TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.) @@ -81,6 +81,12 @@ namespace Google.Protobuf.Collections this.allowNullValues = allowNullValues; } + /// <summary> + /// Creates a deep clone of this object. + /// </summary> + /// <returns> + /// A deep clone of this object. + /// </returns> public MapField<TKey, TValue> Clone() { var clone = new MapField<TKey, TValue>(allowNullValues); @@ -100,6 +106,15 @@ namespace Google.Protobuf.Collections return clone; } + /// <summary> + /// Adds the specified key/value pair to the map. + /// </summary> + /// <remarks> + /// This operation fails if the key already exists in the map. To replace an existing entry, use the indexer. + /// </remarks> + /// <param name="key">The key to add</param> + /// <param name="value">The value to add.</param> + /// <exception cref="System.ArgumentException">The given key already exists in map.</exception> public void Add(TKey key, TValue value) { // Validation of arguments happens in ContainsKey and the indexer @@ -110,12 +125,22 @@ namespace Google.Protobuf.Collections this[key] = value; } + /// <summary> + /// Determines whether the specified key is present in the map. + /// </summary> + /// <param name="key">The key to check.</param> + /// <returns><c>true</c> if the map contains the given key; <c>false</c> otherwise.</returns> public bool ContainsKey(TKey key) { Preconditions.CheckNotNullUnconstrained(key, "key"); return map.ContainsKey(key); } + /// <summary> + /// Removes the entry identified by the given key from the map. + /// </summary> + /// <param name="key">The key indicating the entry to remove from the map.</param> + /// <returns><c>true</c> if the map contained the given key before the entry was removed; <c>false</c> otherwise.</returns> public bool Remove(TKey key) { Preconditions.CheckNotNullUnconstrained(key, "key"); @@ -132,6 +157,14 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Gets the value associated with the specified key. + /// </summary> + /// <param name="key">The key whose value to get.</param> + /// <param name="value">When this method returns, the value associated with the specified key, if the key is found; + /// otherwise, the default value for the type of the <paramref name="value"/> parameter. + /// This parameter is passed uninitialized.</param> + /// <returns><c>true</c> if the map contains an element with the specified key; otherwise, <c>false</c>.</returns> public bool TryGetValue(TKey key, out TValue value) { LinkedListNode<KeyValuePair<TKey, TValue>> node; @@ -147,6 +180,13 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Gets or sets the value associated with the specified key. + /// </summary> + /// <param name="key">The key of the value to get or set.</param> + /// <exception cref="KeyNotFoundException">The property is retrieved and key does not exist in the collection.</exception> + /// <returns>The value associated with the specified key. If the specified key is not found, + /// a get operation throws a <see cref="KeyNotFoundException"/>, and a set operation creates a new element with the specified key.</returns> public TValue this[TKey key] { get @@ -182,9 +222,21 @@ namespace Google.Protobuf.Collections } // TODO: Make these views? + + /// <summary> + /// Gets a collection containing the keys in the map. + /// </summary> public ICollection<TKey> Keys { get { return list.Select(t => t.Key).ToList(); } } + + /// <summary> + /// Gets a collection containing the values in the map. + /// </summary> public ICollection<TValue> Values { get { return list.Select(t => t.Value).ToList(); } } + /// <summary> + /// Adds the specified entries to the map. + /// </summary> + /// <param name="entries">The entries to add to the map.</param> public void Add(IDictionary<TKey, TValue> entries) { Preconditions.CheckNotNull(entries, "entries"); @@ -194,27 +246,51 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Returns an enumerator that iterates through the collection. + /// </summary> + /// <returns> + /// An enumerator that can be used to iterate through the collection. + /// </returns> public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return list.GetEnumerator(); } + /// <summary> + /// Returns an enumerator that iterates through a collection. + /// </summary> + /// <returns> + /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection. + /// </returns> IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + /// <summary> + /// Adds the specified item to the map. + /// </summary> + /// <param name="item">The item to add to the map.</param> void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) { Add(item.Key, item.Value); } + /// <summary> + /// Removes all items from the map. + /// </summary> public void Clear() { list.Clear(); map.Clear(); } + /// <summary> + /// Determines whether map contains an entry equivalent to the given key/value pair. + /// </summary> + /// <param name="item">The key/value pair to find.</param> + /// <returns></returns> bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) { TValue value; @@ -222,11 +298,22 @@ namespace Google.Protobuf.Collections && EqualityComparer<TValue>.Default.Equals(item.Value, value); } + /// <summary> + /// Copies the key/value pairs in this map to an array. + /// </summary> + /// <param name="array">The array to copy the entries into.</param> + /// <param name="arrayIndex">The index of the array at which to start copying values.</param> void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { list.CopyTo(array, arrayIndex); } + /// <summary> + /// Removes the specified key/value pair from the map. + /// </summary> + /// <remarks>Both the key and the value must be found for the entry to be removed.</remarks> + /// <param name="item">The key/value pair to remove.</param> + /// <returns><c>true</c> if the key/value pair was found and removed; <c>false</c> otherwise.</returns> bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) { if (item.Key == null) @@ -252,14 +339,34 @@ namespace Google.Protobuf.Collections /// </summary> public bool AllowsNullValues { get { return allowNullValues; } } + /// <summary> + /// Gets the number of elements contained in the map. + /// </summary> public int Count { get { return list.Count; } } + + /// <summary> + /// Gets a value indicating whether the map is read-only. + /// </summary> public bool IsReadOnly { get { return false; } } + /// <summary> + /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. + /// </summary> + /// <param name="other">The <see cref="System.Object" /> to compare with this instance.</param> + /// <returns> + /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. + /// </returns> public override bool Equals(object other) { return Equals(other as MapField<TKey, TValue>); } + /// <summary> + /// Returns a hash code for this instance. + /// </summary> + /// <returns> + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// </returns> public override int GetHashCode() { var valueComparer = EqualityComparer<TValue>.Default; @@ -271,6 +378,14 @@ namespace Google.Protobuf.Collections return hash; } + /// <summary> + /// Compares this map with another for equality. + /// </summary> + /// <remarks> + /// The order of the key/value pairs in the maps is not deemed significant in this comparison. + /// </remarks> + /// <param name="other">The map to compare this with.</param> + /// <returns><c>true</c> if <paramref name="other"/> refers to an equal map; <c>false</c> otherwise.</returns> public bool Equals(MapField<TKey, TValue> other) { if (other == null) @@ -322,6 +437,12 @@ namespace Google.Protobuf.Collections } while (input.MaybeConsumeTag(codec.MapTag)); } + /// <summary> + /// Writes the contents of this map to the given coded output stream, using the specified codec + /// to encode each entry. + /// </summary> + /// <param name="output">The output stream to write to.</param> + /// <param name="codec">The codec to use for each entry.</param> public void WriteTo(CodedOutputStream output, Codec codec) { var message = new Codec.MessageAdapter(codec); @@ -334,6 +455,11 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Calculates the size of this map based on the given entry codec. + /// </summary> + /// <param name="codec">The codec to use to encode each entry.</param> + /// <returns></returns> public int CalculateSize(Codec codec) { if (Count == 0) @@ -446,7 +572,7 @@ namespace Google.Protobuf.Collections } /// <summary> - /// A codec for a specific map field. This contains all the information required to encoded and + /// A codec for a specific map field. This contains all the information required to encode and /// decode the nested messages. /// </summary> public sealed class Codec @@ -455,6 +581,13 @@ namespace Google.Protobuf.Collections private readonly FieldCodec<TValue> valueCodec; private readonly uint mapTag; + /// <summary> + /// Creates a new entry codec based on a separate key codec and value codec, + /// and the tag to use for each map entry. + /// </summary> + /// <param name="keyCodec">The key codec.</param> + /// <param name="valueCodec">The value codec.</param> + /// <param name="mapTag">The map tag to use to introduce each map entry.</param> public Codec(FieldCodec<TKey> keyCodec, FieldCodec<TValue> valueCodec, uint mapTag) { this.keyCodec = keyCodec; diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs index 3ce19c81..c901864a 100644 --- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs +++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs @@ -30,7 +30,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion -using Google.Protobuf.Reflection; using System; using System.Collections; using System.Collections.Generic; @@ -81,6 +80,11 @@ namespace Google.Protobuf.Collections return clone; } + /// <summary> + /// Adds the entries from the given input stream, decoding them with the specified codec. + /// </summary> + /// <param name="input">The input stream to read from.</param> + /// <param name="codec">The codec to use in order to read each entry.</param> public void AddEntriesFrom(CodedInputStream input, FieldCodec<T> codec) { // TODO: Inline some of the Add code, so we can avoid checking the size on every @@ -112,6 +116,12 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Calculates the size of this collection based on the given codec. + /// </summary> + /// <param name="codec">The codec to use when encoding each field.</param> + /// <returns>The number of bytes that would be written to a <see cref="CodedOutputStream"/> by <see cref="WriteTo"/>, + /// using the same codec.</returns> public int CalculateSize(FieldCodec<T> codec) { if (count == 0) @@ -157,6 +167,12 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Writes the contents of this collection to the given <see cref="CodedOutputStream"/>, + /// encoding each value using the specified codec. + /// </summary> + /// <param name="output">The output stream to write to.</param> + /// <param name="codec">The codec to use when encoding each value.</param> public void WriteTo(CodedOutputStream output, FieldCodec<T> codec) { if (count == 0) @@ -200,6 +216,10 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Adds the specified item to the collection. + /// </summary> + /// <param name="item">The item to add.</param> public void Add(T item) { if (item == null) @@ -210,22 +230,40 @@ namespace Google.Protobuf.Collections array[count++] = item; } + /// <summary> + /// Removes all items from the collection. + /// </summary> public void Clear() { array = EmptyArray; count = 0; } + /// <summary> + /// Determines whether this collection contains the given item. + /// </summary> + /// <param name="item">The item to find.</param> + /// <returns><c>true</c> if this collection contains the given item; <c>false</c> otherwise.</returns> public bool Contains(T item) { return IndexOf(item) != -1; } + /// <summary> + /// Copies this collection to the given array. + /// </summary> + /// <param name="array">The array to copy to.</param> + /// <param name="arrayIndex">The first index of the array to copy to.</param> public void CopyTo(T[] array, int arrayIndex) { Array.Copy(this.array, 0, array, arrayIndex, count); } + /// <summary> + /// Removes the specified item from the collection + /// </summary> + /// <param name="item">The item to remove.</param> + /// <returns><c>true</c> if the item was found and removed; <c>false</c> otherwise.</returns> public bool Remove(T item) { int index = IndexOf(item); @@ -239,10 +277,22 @@ namespace Google.Protobuf.Collections return true; } + /// <summary> + /// Gets the number of elements contained in the collection. + /// </summary> public int Count { get { return count; } } + /// <summary> + /// Gets a value indicating whether the collection is read-only. + /// </summary> public bool IsReadOnly { get { return false; } } + // TODO: Remove this overload and just handle it in the one below, at execution time? + + /// <summary> + /// Adds all of the specified values into this collection. + /// </summary> + /// <param name="values">The values to add to this collection.</param> public void Add(RepeatedField<T> values) { if (values == null) @@ -255,6 +305,10 @@ namespace Google.Protobuf.Collections count += values.count; } + /// <summary> + /// Adds all of the specified values into this collection. + /// </summary> + /// <param name="values">The values to add to this collection.</param> public void Add(IEnumerable<T> values) { if (values == null) @@ -268,6 +322,12 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Returns an enumerator that iterates through the collection. + /// </summary> + /// <returns> + /// An enumerator that can be used to iterate through the collection. + /// </returns> public IEnumerator<T> GetEnumerator() { for (int i = 0; i < count; i++) @@ -276,16 +336,35 @@ namespace Google.Protobuf.Collections } } + /// <summary> + /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. + /// </summary> + /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> + /// <returns> + /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. + /// </returns> public override bool Equals(object obj) { return Equals(obj as RepeatedField<T>); } + /// <summary> + /// Returns an enumerator that iterates through a collection. + /// </summary> + /// <returns> + /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection. + /// </returns> IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); - } + } + /// <summary> + /// Returns a hash code for this instance. + /// </summary> + /// <returns> + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// </returns> public override int GetHashCode() { int hash = 0; @@ -296,6 +375,11 @@ namespace Google.Protobuf.Collections return hash; } + /// <summary> + /// Compares this repeated field with another for equality. + /// </summary> + /// <param name="other">The repeated field to compare this with.</param> + /// <returns><c>true</c> if <paramref name="other"/> refers to an equal repeated field; <c>false</c> otherwise.</returns> public bool Equals(RepeatedField<T> other) { if (ReferenceEquals(other, null)) @@ -322,6 +406,12 @@ namespace Google.Protobuf.Collections return true; } + /// <summary> + /// Returns the index of the given item within the collection, or -1 if the item is not + /// present. + /// </summary> + /// <param name="item">The item to find in the collection.</param> + /// <returns>The zero-based index of the item, or -1 if it is not found.</returns> public int IndexOf(T item) { if (item == null) @@ -340,6 +430,11 @@ namespace Google.Protobuf.Collections return -1; } + /// <summary> + /// Inserts the given item at the specified index. + /// </summary> + /// <param name="index">The index at which to insert the item.</param> + /// <param name="item">The item to insert.</param> public void Insert(int index, T item) { if (item == null) @@ -356,6 +451,10 @@ namespace Google.Protobuf.Collections count++; } + /// <summary> + /// Removes the item at the given index. + /// </summary> + /// <param name="index">The zero-based index of the item to remove.</param> public void RemoveAt(int index) { if (index < 0 || index >= count) @@ -367,6 +466,14 @@ namespace Google.Protobuf.Collections array[count] = default(T); } + /// <summary> + /// Gets or sets the item at the specified index. + /// </summary> + /// <value> + /// The element at the specified index. + /// </value> + /// <param name="index">The zero-based index of the element to get or set.</param> + /// <returns>The item at the specified index.</returns> public T this[int index] { get |