Document everything, and turn on errors if we fail to document anything in the future.
This commit is contained in:
parent
dc80689af3
commit
811fc89f0e
@ -105,23 +105,35 @@ namespace Google.Protobuf
|
||||
get { return bytes.Length; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this byte string is empty, <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsEmpty
|
||||
{
|
||||
get { return Length == 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="ByteString"/> into a byte array.
|
||||
/// </summary>
|
||||
/// <remarks>The data is copied - changes to the returned array will not be reflected in this <c>ByteString</c>.</remarks>
|
||||
/// <returns>A byte array with the same data as this <c>ByteString</c>.</returns>
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
return (byte[]) bytes.Clone();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="ByteString"/> into a standard base64 representation.
|
||||
/// </summary>
|
||||
/// <returns>A base64 representation of this <c>ByteString</c>.</returns>
|
||||
public string ToBase64()
|
||||
{
|
||||
return Convert.ToBase64String(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a ByteString from the Base64 Encoded String.
|
||||
/// Constructs a <see cref="ByteString" /> from the Base64 Encoded String.
|
||||
/// </summary>
|
||||
public static ByteString FromBase64(string bytes)
|
||||
{
|
||||
@ -131,7 +143,7 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a ByteString from the given array. The contents
|
||||
/// Constructs a <see cref="ByteString" /> from the given array. The contents
|
||||
/// are copied, so further modifications to the array will not
|
||||
/// be reflected in the returned ByteString.
|
||||
/// This method can also be invoked in <c>ByteString.CopyFrom(0xaa, 0xbb, ...)</c> form
|
||||
@ -143,7 +155,7 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a ByteString from a portion of a byte array.
|
||||
/// Constructs a <see cref="ByteString" /> from a portion of a byte array.
|
||||
/// </summary>
|
||||
public static ByteString CopyFrom(byte[] bytes, int offset, int count)
|
||||
{
|
||||
@ -153,7 +165,7 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ByteString by encoding the specified text with
|
||||
/// Creates a new <see cref="ByteString" /> by encoding the specified text with
|
||||
/// the given encoding.
|
||||
/// </summary>
|
||||
public static ByteString CopyFrom(string text, Encoding encoding)
|
||||
@ -162,7 +174,7 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ByteString by encoding the specified text in UTF-8.
|
||||
/// Creates a new <see cref="ByteString" /> by encoding the specified text in UTF-8.
|
||||
/// </summary>
|
||||
public static ByteString CopyFromUtf8(string text)
|
||||
{
|
||||
@ -177,21 +189,46 @@ namespace Google.Protobuf
|
||||
get { return bytes[index]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="ByteString"/> into a string by applying the given encoding.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method should only be used to convert binary data which was the result of encoding
|
||||
/// text with the given encoding.
|
||||
/// </remarks>
|
||||
/// <param name="encoding">The encoding to use to decode the binary data into text.</param>
|
||||
/// <returns>The result of decoding the binary data with the given decoding.</returns>
|
||||
public string ToString(Encoding encoding)
|
||||
{
|
||||
return encoding.GetString(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="ByteString"/> into a string by applying the UTF-8 encoding.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method should only be used to convert binary data which was the result of encoding
|
||||
/// text with UTF-8.
|
||||
/// </remarks>
|
||||
/// <returns>The result of decoding the binary data with the given decoding.</returns>
|
||||
public string ToStringUtf8()
|
||||
{
|
||||
return ToString(Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an iterator over the bytes in this <see cref="ByteString"/>.
|
||||
/// </summary>
|
||||
/// <returns>An iterator over the bytes in this object.</returns>
|
||||
public IEnumerator<byte> GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<byte>) bytes).GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an iterator over the bytes in this <see cref="ByteString"/>.
|
||||
/// </summary>
|
||||
/// <returns>An iterator over the bytes in this object.</returns>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
@ -206,6 +243,12 @@ namespace Google.Protobuf
|
||||
return new CodedInputStream(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two byte strings for equality.
|
||||
/// </summary>
|
||||
/// <param name="lhs">The first byte string to compare.</param>
|
||||
/// <param name="rhs">The second byte string to compare.</param>
|
||||
/// <returns><c>true</c> if the byte strings are equal; false otherwise.</returns>
|
||||
public static bool operator ==(ByteString lhs, ByteString rhs)
|
||||
{
|
||||
if (ReferenceEquals(lhs, rhs))
|
||||
@ -230,6 +273,12 @@ namespace Google.Protobuf
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two byte strings for inequality.
|
||||
/// </summary>
|
||||
/// <param name="lhs">The first byte string to compare.</param>
|
||||
/// <param name="rhs">The second byte string to compare.</param>
|
||||
/// <returns><c>false</c> if the byte strings are equal; true otherwise.</returns>
|
||||
public static bool operator !=(ByteString lhs, ByteString rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
@ -237,11 +286,21 @@ namespace Google.Protobuf
|
||||
|
||||
// TODO(jonskeet): CopyTo if it turns out to be required
|
||||
|
||||
/// <summary>
|
||||
/// Compares this byte string with another object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare this with.</param>
|
||||
/// <returns><c>true</c> if <paramref name="obj"/> refers to an equal <see cref="ByteString"/>; <c>false</c> otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return this == (obj as ByteString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this object. Two equal byte strings
|
||||
/// will return the same hash code.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for this object.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int ret = 23;
|
||||
@ -252,6 +311,11 @@ namespace Google.Protobuf
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares this byte string with another.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="ByteString"/> to compare this with.</param>
|
||||
/// <returns><c>true</c> if <paramref name="other"/> refers to an equal byte string; <c>false</c> otherwise.</returns>
|
||||
public bool Equals(ByteString other)
|
||||
{
|
||||
return this == other;
|
||||
|
@ -66,7 +66,7 @@ namespace Google.Protobuf
|
||||
|
||||
internal const int DefaultRecursionLimit = 64;
|
||||
internal const int DefaultSizeLimit = 64 << 20; // 64MB
|
||||
public const int BufferSize = 4096;
|
||||
internal const int BufferSize = 4096;
|
||||
|
||||
/// <summary>
|
||||
/// The total number of bytes read before the current buffer. The
|
||||
|
@ -297,6 +297,10 @@ namespace Google.Protobuf
|
||||
WriteInt32(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an sfixed32 value, without a tag, to the stream.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public void WriteSFixed32(int value)
|
||||
{
|
||||
WriteRawLittleEndian32((uint) value);
|
||||
@ -649,6 +653,9 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flushes any buffered data to the underlying stream (if there is one).
|
||||
/// </summary>
|
||||
public void Flush()
|
||||
{
|
||||
if (output != null)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -41,76 +41,152 @@ namespace Google.Protobuf
|
||||
public static class FieldCodec
|
||||
{
|
||||
// TODO: Avoid the "dual hit" of lambda expressions: create open delegates instead. (At least test...)
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a string field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<string> ForString(uint tag)
|
||||
{
|
||||
return new FieldCodec<string>(input => input.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a bytes field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ByteString> ForBytes(uint tag)
|
||||
{
|
||||
return new FieldCodec<ByteString>(input => input.ReadBytes(), (output, value) => output.WriteBytes(value), CodedOutputStream.ComputeBytesSize, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a bool field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<bool> ForBool(uint tag)
|
||||
{
|
||||
return new FieldCodec<bool>(input => input.ReadBool(), (output, value) => output.WriteBool(value), CodedOutputStream.ComputeBoolSize, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an int32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForInt32(uint tag)
|
||||
{
|
||||
return new FieldCodec<int>(input => input.ReadInt32(), (output, value) => output.WriteInt32(value), CodedOutputStream.ComputeInt32Size, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an sint32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForSInt32(uint tag)
|
||||
{
|
||||
return new FieldCodec<int>(input => input.ReadSInt32(), (output, value) => output.WriteSInt32(value), CodedOutputStream.ComputeSInt32Size, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a fixed32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<uint> ForFixed32(uint tag)
|
||||
{
|
||||
return new FieldCodec<uint>(input => input.ReadFixed32(), (output, value) => output.WriteFixed32(value), 4, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an sfixed32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForSFixed32(uint tag)
|
||||
{
|
||||
return new FieldCodec<int>(input => input.ReadSFixed32(), (output, value) => output.WriteSFixed32(value), 4, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a uint32 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<uint> ForUInt32(uint tag)
|
||||
{
|
||||
return new FieldCodec<uint>(input => input.ReadUInt32(), (output, value) => output.WriteUInt32(value), CodedOutputStream.ComputeUInt32Size, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an int64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForInt64(uint tag)
|
||||
{
|
||||
return new FieldCodec<long>(input => input.ReadInt64(), (output, value) => output.WriteInt64(value), CodedOutputStream.ComputeInt64Size, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an sint64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForSInt64(uint tag)
|
||||
{
|
||||
return new FieldCodec<long>(input => input.ReadSInt64(), (output, value) => output.WriteSInt64(value), CodedOutputStream.ComputeSInt64Size, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a fixed64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ulong> ForFixed64(uint tag)
|
||||
{
|
||||
return new FieldCodec<ulong>(input => input.ReadFixed64(), (output, value) => output.WriteFixed64(value), 8, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an sfixed64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForSFixed64(uint tag)
|
||||
{
|
||||
return new FieldCodec<long>(input => input.ReadSFixed64(), (output, value) => output.WriteSFixed64(value), 8, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a uint64 field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ulong> ForUInt64(uint tag)
|
||||
{
|
||||
return new FieldCodec<ulong>(input => input.ReadUInt64(), (output, value) => output.WriteUInt64(value), CodedOutputStream.ComputeUInt64Size, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a float field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<float> ForFloat(uint tag)
|
||||
{
|
||||
return new FieldCodec<float>(input => input.ReadFloat(), (output, value) => output.WriteFloat(value), CodedOutputStream.ComputeFloatSize, tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a double field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<double> ForDouble(uint tag)
|
||||
{
|
||||
return new FieldCodec<double>(input => input.ReadDouble(), (output, value) => output.WriteDouble(value), CodedOutputStream.ComputeDoubleSize, tag);
|
||||
@ -118,6 +194,14 @@ namespace Google.Protobuf
|
||||
|
||||
// Enums are tricky. We can probably use expression trees to build these delegates automatically,
|
||||
// but it's easy to generate the code for it.
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for an enum field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <param name="toInt32">A conversion function from <see cref="Int32"/> to the enum type.</param>
|
||||
/// <param name="fromInt32">A conversion function from the enum type to <see cref="Int32"/>.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<T> ForEnum<T>(uint tag, Func<T, int> toInt32, Func<int, T> fromInt32)
|
||||
{
|
||||
return new FieldCodec<T>(input => fromInt32(
|
||||
@ -126,6 +210,12 @@ namespace Google.Protobuf
|
||||
value => CodedOutputStream.ComputeEnumSize(toInt32(value)), tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a codec suitable for a message field with the given tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <param name="parser">A parser to use for the message type.</param>
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<T> ForMessage<T>(uint tag, MessageParser<T> parser) where T : IMessage<T>
|
||||
{
|
||||
return new FieldCodec<T>(input => { T message = parser.CreateTemplate(); input.ReadMessage(message); return message; },
|
||||
@ -344,8 +434,20 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
internal int FixedSize { get { return fixedSize; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tag of the codec.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The tag of the codec.
|
||||
/// </value>
|
||||
public uint Tag { get { return tag; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default value of the codec's type.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The default value of the codec's type.
|
||||
/// </value>
|
||||
public T DefaultValue { get { return defaultValue; } }
|
||||
|
||||
/// <summary>
|
||||
@ -360,6 +462,11 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a value of the codec type from the given <see cref="CodedInputStream"/>.
|
||||
/// </summary>
|
||||
/// <param name="input">The input stream to read from.</param>
|
||||
/// <returns>The value read from the stream.</returns>
|
||||
public T Read(CodedInputStream input)
|
||||
{
|
||||
return reader(input);
|
||||
|
@ -24,12 +24,14 @@
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
|
||||
<DocumentationFile>bin\Debug\Google.Protobuf.xml</DocumentationFile>
|
||||
<NoWarn>1591, 1570, 1571, 1572, 1573, 1574</NoWarn>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@ -37,12 +39,14 @@
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
|
||||
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
|
||||
<NoWarn>1591, 1570, 1571, 1572, 1573, 1574</NoWarn>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@ -50,7 +54,8 @@
|
||||
<OutputPath>bin\ReleaseSigned</OutputPath>
|
||||
<IntermediateOutputPath>obj\ReleaseSigned\</IntermediateOutputPath>
|
||||
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
|
||||
<NoWarn>1591, 1570, 1571, 1572, 1573, 1574</NoWarn>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<DefineConstants>TRACE;SIGNED</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
@ -58,6 +63,7 @@
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>C:\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib" />
|
||||
|
@ -91,8 +91,9 @@ namespace Google.Protobuf
|
||||
|
||||
/// <summary>
|
||||
/// Generic interface for a deeply cloneable type.
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// All generated messages implement this interface, but so do some non-message types.
|
||||
/// Additionally, due to the type constraint on <c>T</c> in <see cref="IMessage{T}"/>,
|
||||
/// it is simpler to keep this as a separate interface.
|
||||
|
@ -45,7 +45,7 @@ namespace Google.Protobuf
|
||||
{
|
||||
}
|
||||
|
||||
public static InvalidProtocolBufferException TruncatedMessage()
|
||||
internal static InvalidProtocolBufferException TruncatedMessage()
|
||||
{
|
||||
return new InvalidProtocolBufferException(
|
||||
"While parsing a protocol message, the input ended unexpectedly " +
|
||||
@ -61,12 +61,15 @@ namespace Google.Protobuf
|
||||
"which claimed to have negative size.");
|
||||
}
|
||||
|
||||
public static InvalidProtocolBufferException MalformedVarint()
|
||||
internal static InvalidProtocolBufferException MalformedVarint()
|
||||
{
|
||||
return new InvalidProtocolBufferException(
|
||||
"CodedInputStream encountered a malformed varint.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an exception for an error condition of an invalid tag being encountered.
|
||||
/// </summary>
|
||||
public static InvalidProtocolBufferException InvalidTag()
|
||||
{
|
||||
return new InvalidProtocolBufferException(
|
||||
|
@ -114,11 +114,20 @@ namespace Google.Protobuf
|
||||
|
||||
private readonly Settings settings;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new formatted with the given settings.
|
||||
/// </summary>
|
||||
/// <param name="settings">The settings.</param>
|
||||
public JsonFormatter(Settings settings)
|
||||
{
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats the specified message as JSON.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to format.</param>
|
||||
/// <returns>The formatted message.</returns>
|
||||
public string Format(IMessage message)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
@ -768,6 +777,10 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public bool FormatDefaultValues { get { return formatDefaultValues; } }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Settings"/> object with the specified formatting of default values.
|
||||
/// </summary>
|
||||
/// <param name="formatDefaultValues"><c>true</c> if default values (0, empty strings etc) should be formatted; <c>false</c> otherwise.</param>
|
||||
public Settings(bool formatDefaultValues)
|
||||
{
|
||||
this.formatDefaultValues = formatDefaultValues;
|
||||
|
@ -39,6 +39,11 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public static class MessageExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Merges data from the given byte array into an existing message.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to merge the data into.</param>
|
||||
/// <param name="data">The data to merge, which must be protobuf-encoded binary data.</param>
|
||||
public static void MergeFrom(this IMessage message, byte[] data)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
@ -48,6 +53,11 @@ namespace Google.Protobuf
|
||||
input.CheckLastTagWas(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges data from the given byte string into an existing message.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to merge the data into.</param>
|
||||
/// <param name="data">The data to merge, which must be protobuf-encoded binary data.</param>
|
||||
public static void MergeFrom(this IMessage message, ByteString data)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
@ -57,6 +67,11 @@ namespace Google.Protobuf
|
||||
input.CheckLastTagWas(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges data from the given stream into an existing message.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to merge the data into.</param>
|
||||
/// <param name="input">Stream containing the data to merge, which must be protobuf-encoded binary data.</param>
|
||||
public static void MergeFrom(this IMessage message, Stream input)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
@ -66,6 +81,15 @@ namespace Google.Protobuf
|
||||
codedInput.CheckLastTagWas(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges length-delimited data from the given stream into an existing message.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The stream is expected to contain a length and then the data. Only the amount of data
|
||||
/// specified by the length will be consumed.
|
||||
/// </remarks>
|
||||
/// <param name="message">The message to merge the data into.</param>
|
||||
/// <param name="input">Stream containing the data to merge, which must be protobuf-encoded binary data.</param>
|
||||
public static void MergeDelimitedFrom(this IMessage message, Stream input)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
@ -75,6 +99,11 @@ namespace Google.Protobuf
|
||||
message.MergeFrom(limitedStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given message into a byte array in protobuf encoding.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to convert.</param>
|
||||
/// <returns>The message data as a byte array.</returns>
|
||||
public static byte[] ToByteArray(this IMessage message)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
@ -85,6 +114,11 @@ namespace Google.Protobuf
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the given message data to the given stream in protobuf encoding.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to write to the stream.</param>
|
||||
/// <param name="output">The stream to write to.</param>
|
||||
public static void WriteTo(this IMessage message, Stream output)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
@ -94,6 +128,11 @@ namespace Google.Protobuf
|
||||
codedOutput.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the length and then data of the given message to a stream.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to write.</param>
|
||||
/// <param name="output">The output stream to write to.</param>
|
||||
public static void WriteDelimitedTo(this IMessage message, Stream output)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
@ -104,6 +143,11 @@ namespace Google.Protobuf
|
||||
codedOutput.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given message into a byte string in protobuf encoding.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to convert.</param>
|
||||
/// <returns>The message data as a byte string.</returns>
|
||||
public static ByteString ToByteString(this IMessage message)
|
||||
{
|
||||
Preconditions.CheckNotNull(message, "message");
|
||||
|
@ -90,6 +90,11 @@ namespace Google.Protobuf
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a message from the given byte string.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <returns>The parsed message.</returns>
|
||||
public T ParseFrom(ByteString data)
|
||||
{
|
||||
Preconditions.CheckNotNull(data, "data");
|
||||
@ -98,6 +103,11 @@ namespace Google.Protobuf
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a message from the given stream.
|
||||
/// </summary>
|
||||
/// <param name="input">The stream to parse.</param>
|
||||
/// <returns>The parsed message.</returns>
|
||||
public T ParseFrom(Stream input)
|
||||
{
|
||||
T message = factory();
|
||||
@ -105,6 +115,15 @@ namespace Google.Protobuf
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a length-delimited message from the given stream.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The stream is expected to contain a length and then the data. Only the amount of data
|
||||
/// specified by the length will be consumed.
|
||||
/// </remarks>
|
||||
/// <param name="input">The stream to parse.</param>
|
||||
/// <returns>The parsed message.</returns>
|
||||
public T ParseDelimitedFrom(Stream input)
|
||||
{
|
||||
T message = factory();
|
||||
@ -112,6 +131,11 @@ namespace Google.Protobuf
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a message from the given coded input stream.
|
||||
/// </summary>
|
||||
/// <param name="input">The stream to parse.</param>
|
||||
/// <returns>The parsed message.</returns>
|
||||
public T ParseFrom(CodedInputStream input)
|
||||
{
|
||||
T message = factory();
|
||||
|
@ -61,6 +61,9 @@ namespace Google.Protobuf.Reflection
|
||||
get { return index; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the name of the entity (field, message etc) being described.
|
||||
/// </summary>
|
||||
public abstract string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -51,11 +51,20 @@ namespace Google.Protobuf.Reflection
|
||||
}
|
||||
|
||||
internal EnumValueDescriptorProto Proto { get { return proto; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the name of the enum value described by this object.
|
||||
/// </summary>
|
||||
public override string Name { get { return proto.Name; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number associated with this enum value.
|
||||
/// </summary>
|
||||
public int Number { get { return Proto.Number; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the enum descriptor that this value is part of.
|
||||
/// </summary>
|
||||
public EnumDescriptor EnumDescriptor { get { return enumDescriptor; } }
|
||||
}
|
||||
}
|
@ -93,6 +93,15 @@ namespace Google.Protobuf.Reflection
|
||||
|
||||
internal FieldDescriptorProto Proto { get { return proto; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the accessor for this field, or <c>null</c> if this descriptor does
|
||||
/// not support reflective access.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// While a <see cref="FieldDescriptor"/> describes the field, it does not provide
|
||||
/// any way of obtaining or changing the value of the field within a specific message;
|
||||
/// that is the responsibility of the accessor.
|
||||
/// </remarks>
|
||||
public IFieldAccessor Accessor { get { return accessor; } }
|
||||
|
||||
/// <summary>
|
||||
@ -141,43 +150,61 @@ namespace Google.Protobuf.Reflection
|
||||
default:
|
||||
throw new ArgumentException("Invalid type specified");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this field is a repeated field; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsRepeated
|
||||
{
|
||||
get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_REPEATED; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this field is a map field; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsMap
|
||||
{
|
||||
get { return fieldType == FieldType.Message && messageType.Proto.Options != null && messageType.Proto.Options.MapEntry; }
|
||||
}
|
||||
|
||||
// TODO(jonskeet): Check whether this is correct with proto3, where we default to packed...
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this field is a packed, repeated field; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsPacked
|
||||
{
|
||||
get { return Proto.Options != null && Proto.Options.Packed; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the field's containing type. For extensions, this is the type being
|
||||
/// extended, not the location where the extension was defined. See
|
||||
/// <see cref="ExtensionScope" />.
|
||||
/// Get the field's containing message type.
|
||||
/// </summary>
|
||||
public MessageDescriptor ContainingType
|
||||
{
|
||||
get { return containingType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the oneof containing this field, or <c>null</c> if it is not part of a oneof.
|
||||
/// </summary>
|
||||
public OneofDescriptor ContainingOneof
|
||||
{
|
||||
get { return containingOneof; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the type of the field.
|
||||
/// </summary>
|
||||
public FieldType FieldType
|
||||
{
|
||||
get { return fieldType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the field number declared in the proto file.
|
||||
/// </summary>
|
||||
public int FieldNumber
|
||||
{
|
||||
get { return Proto.Number; }
|
||||
|
@ -33,28 +33,81 @@
|
||||
namespace Google.Protobuf.Reflection
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of all the possible field types. The odd formatting is to make it very clear
|
||||
/// which attribute applies to which value, while maintaining a compact format.
|
||||
/// Enumeration of all the possible field types.
|
||||
/// </summary>
|
||||
public enum FieldType
|
||||
{
|
||||
/// <summary>
|
||||
/// The <c>double</c> field type.
|
||||
/// </summary>
|
||||
Double,
|
||||
/// <summary>
|
||||
/// The <c>float</c> field type.
|
||||
/// </summary>
|
||||
Float,
|
||||
/// <summary>
|
||||
/// The <c>int64</c> field type.
|
||||
/// </summary>
|
||||
Int64,
|
||||
/// <summary>
|
||||
/// The <c>uint64</c> field type.
|
||||
/// </summary>
|
||||
UInt64,
|
||||
/// <summary>
|
||||
/// The <c>int32</c> field type.
|
||||
/// </summary>
|
||||
Int32,
|
||||
/// <summary>
|
||||
/// The <c>fixed64</c> field type.
|
||||
/// </summary>
|
||||
Fixed64,
|
||||
/// <summary>
|
||||
/// The <c>fixed32</c> field type.
|
||||
/// </summary>
|
||||
Fixed32,
|
||||
/// <summary>
|
||||
/// The <c>bool</c> field type.
|
||||
/// </summary>
|
||||
Bool,
|
||||
/// <summary>
|
||||
/// The <c>string</c> field type.
|
||||
/// </summary>
|
||||
String,
|
||||
/// <summary>
|
||||
/// The field type used for groups (not supported in this implementation).
|
||||
/// </summary>
|
||||
Group,
|
||||
/// <summary>
|
||||
/// The field type used for message fields.
|
||||
/// </summary>
|
||||
Message,
|
||||
/// <summary>
|
||||
/// The <c>bytes</c> field type.
|
||||
/// </summary>
|
||||
Bytes,
|
||||
/// <summary>
|
||||
/// The <c>uint32</c> field type.
|
||||
/// </summary>
|
||||
UInt32,
|
||||
/// <summary>
|
||||
/// The <c>sfixed32</c> field type.
|
||||
/// </summary>
|
||||
SFixed32,
|
||||
/// <summary>
|
||||
/// The <c>sfixed64</c> field type.
|
||||
/// </summary>
|
||||
SFixed64,
|
||||
/// <summary>
|
||||
/// The <c>sint32</c> field type.
|
||||
/// </summary>
|
||||
SInt32,
|
||||
/// <summary>
|
||||
/// The <c>sint64</c> field type.
|
||||
/// </summary>
|
||||
SInt64,
|
||||
/// <summary>
|
||||
/// The field type used for enum fields.
|
||||
/// </summary>
|
||||
Enum
|
||||
}
|
||||
}
|
@ -51,18 +51,7 @@ namespace Google.Protobuf.Reflection
|
||||
private readonly IList<FileDescriptor> dependencies;
|
||||
private readonly IList<FileDescriptor> publicDependencies;
|
||||
private readonly DescriptorPool pool;
|
||||
|
||||
public enum ProtoSyntax
|
||||
{
|
||||
Proto2,
|
||||
Proto3
|
||||
}
|
||||
|
||||
public ProtoSyntax Syntax
|
||||
{
|
||||
get { return proto.Syntax == "proto3" ? ProtoSyntax.Proto3 : ProtoSyntax.Proto2; }
|
||||
}
|
||||
|
||||
|
||||
private FileDescriptor(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo)
|
||||
{
|
||||
this.descriptorData = descriptorData;
|
||||
@ -368,7 +357,13 @@ namespace Google.Protobuf.Reflection
|
||||
throw new ArgumentException("Invalid embedded descriptor for \"" + proto.Name + "\".", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "FileDescriptor for " + proto.Name;
|
||||
|
@ -37,8 +37,19 @@ namespace Google.Protobuf.Reflection
|
||||
/// </summary>
|
||||
public interface IDescriptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the name of the entity (message, field etc) being described.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the fully-qualified name of the entity being described.
|
||||
/// </summary>
|
||||
string FullName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the descriptor for the .proto file that this entity is part of.
|
||||
/// </summary>
|
||||
FileDescriptor File { get; }
|
||||
}
|
||||
}
|
@ -30,6 +30,9 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Google.Protobuf.Reflection
|
||||
{
|
||||
/// <summary>
|
||||
@ -64,7 +67,7 @@ namespace Google.Protobuf.Reflection
|
||||
/// Repeated fields are mutated by fetching the value and manipulating it as a list.
|
||||
/// Map fields are mutated by fetching the value and manipulating it as a dictionary.
|
||||
/// </remarks>
|
||||
/// <exception cref="InvalidOperationException">The field is not a "simple" field, or the message is frozen.</exception>
|
||||
/// <exception cref="InvalidOperationException">The field is not a "simple" field.</exception>
|
||||
void SetValue(object message, object value);
|
||||
}
|
||||
}
|
@ -30,7 +30,6 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
@ -163,6 +162,9 @@ namespace Google.Protobuf.Reflection
|
||||
get { return enumTypes; }
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// An unmodifiable list of the "oneof" field collections in this message type.
|
||||
/// </value>
|
||||
public IList<OneofDescriptor> Oneofs
|
||||
{
|
||||
get { return oneofs; }
|
||||
@ -276,7 +278,7 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// Retrieves the descriptor for the field with the given name.
|
||||
/// </summary>
|
||||
/// <param name="number">Number of the field to retrieve the descriptor for</param>
|
||||
/// <param name="name">Name of the field to retrieve the descriptor for</param>
|
||||
/// <returns>The descriptor for the given field</returns>
|
||||
/// <exception cref="KeyNotFoundException">The message descriptor does not contain a field
|
||||
/// with the given name</exception>
|
||||
|
@ -58,6 +58,12 @@ namespace Google.Protobuf.Reflection
|
||||
clearDelegate = ReflectionUtil.CreateActionObject(clearMethod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the descriptor for this oneof.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The descriptor of the oneof.
|
||||
/// </value>
|
||||
public OneofDescriptor Descriptor { get { return descriptor; } }
|
||||
|
||||
/// <summary>
|
||||
|
@ -32,11 +32,14 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Google.Protobuf.Compatibility;
|
||||
|
||||
namespace Google.Protobuf.Reflection
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a "oneof" field collection in a message type: a set of
|
||||
/// fields of which at most one can be set in any particular message.
|
||||
/// </summary>
|
||||
public sealed class OneofDescriptor : DescriptorBase
|
||||
{
|
||||
private readonly OneofDescriptorProto proto;
|
||||
@ -59,13 +62,33 @@ namespace Google.Protobuf.Reflection
|
||||
/// </summary>
|
||||
public override string Name { get { return proto.Name; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the message type containing this oneof.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The message type containing this oneof.
|
||||
/// </value>
|
||||
public MessageDescriptor ContainingType
|
||||
{
|
||||
get { return containingType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the fields within this oneof, in declaration order.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The fields within this oneof, in declaration order.
|
||||
/// </value>
|
||||
public IList<FieldDescriptor> Fields { get { return fields; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an accessor for reflective access to the values associated with the oneof
|
||||
/// in a particular message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The accessor used for reflective access, or <c>null</c> if reflection is not
|
||||
/// supported by this descriptor.
|
||||
/// </value>
|
||||
public OneofAccessor Accessor { get { return accessor; } }
|
||||
|
||||
internal void CrossLink()
|
||||
|
@ -38,7 +38,13 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
// providing a conversion to TimeSpan and convenience operators.
|
||||
public partial class Duration
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of nanoseconds in a second.
|
||||
/// </summary>
|
||||
public const int NanosecondsPerSecond = 1000000000;
|
||||
/// <summary>
|
||||
/// The number of nanoseconds in a BCL tick (as used by <see cref="TimeSpan"/> and <see cref="DateTime"/>).
|
||||
/// </summary>
|
||||
public const int NanosecondsPerTick = 100;
|
||||
|
||||
/// <summary>
|
||||
|
@ -43,16 +43,35 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
/// </summary>
|
||||
public static class TimeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts the given <see cref="DateTime"/> to a <see cref="Timestamp"/>.
|
||||
/// </summary>
|
||||
/// <param name="dateTime">The date and time to convert to a timestamp.</param>
|
||||
/// <exception cref="ArgumentException">The <paramref name="dateTime"/> value has a <see cref="DateTime.Kind"/>other than <c>Utc</c>.</exception>
|
||||
/// <returns>The converted timestamp.</returns>
|
||||
public static Timestamp ToTimestamp(this DateTime dateTime)
|
||||
{
|
||||
return Timestamp.FromDateTime(dateTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given <see cref="DateTimeOffset"/> to a <see cref="Timestamp"/>
|
||||
/// </summary>
|
||||
/// <remarks>The offset is taken into consideration when converting the value (so the same instant in time
|
||||
/// is represented) but is not a separate part of the resulting value. In other words, there is no
|
||||
/// roundtrip operation to retrieve the original <c>DateTimeOffset</c>.</remarks>
|
||||
/// <param name="dateTimeOffset">The date and time (with UTC offset) to convert to a timestamp.</param>
|
||||
/// <returns>The converted timestamp.</returns>
|
||||
public static Timestamp ToTimestamp(this DateTimeOffset dateTimeOffset)
|
||||
{
|
||||
return Timestamp.FromDateTimeOffset(dateTimeOffset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given <see cref="TimeSpan"/> to a <see cref="Duration"/>.
|
||||
/// </summary>
|
||||
/// <param name="timeSpan">The time span to convert.</param>
|
||||
/// <returns>The converted duration.</returns>
|
||||
public static Duration ToDuration(this TimeSpan timeSpan)
|
||||
{
|
||||
return Duration.FromTimeSpan(timeSpan);
|
||||
|
@ -136,9 +136,12 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified <see cref="DateTimeOffset"/> to a <see cref="Timestamp"/>.
|
||||
/// Converts the given <see cref="DateTimeOffset"/> to a <see cref="Timestamp"/>
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <remarks>The offset is taken into consideration when converting the value (so the same instant in time
|
||||
/// is represented) but is not a separate part of the resulting value. In other words, there is no
|
||||
/// roundtrip operation to retrieve the original <c>DateTimeOffset</c>.</remarks>
|
||||
/// <param name="dateTimeOffset">The date and time (with UTC offset) to convert to a timestamp.</param>
|
||||
/// <returns>The converted timestamp.</returns>
|
||||
public static Timestamp FromDateTimeOffset(DateTimeOffset dateTimeOffset)
|
||||
{
|
||||
|
@ -30,9 +30,6 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using Google.Protobuf.Reflection;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
/// <summary>
|
||||
@ -59,13 +56,34 @@ namespace Google.Protobuf
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Wire types within protobuf encoding.
|
||||
/// </summary>
|
||||
public enum WireType : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Variable-length integer.
|
||||
/// </summary>
|
||||
Varint = 0,
|
||||
/// <summary>
|
||||
/// A fixed-length 64-bit value.
|
||||
/// </summary>
|
||||
Fixed64 = 1,
|
||||
/// <summary>
|
||||
/// A length-delimited value, i.e. a length followed by that many bytes of data.
|
||||
/// </summary>
|
||||
LengthDelimited = 2,
|
||||
/// <summary>
|
||||
/// A "start group" value - not supported by this implementation.
|
||||
/// </summary>
|
||||
StartGroup = 3,
|
||||
/// <summary>
|
||||
/// An "end group" value - not supported by this implementation.
|
||||
/// </summary>
|
||||
EndGroup = 4,
|
||||
/// <summary>
|
||||
/// A fixed-length 32-bit value.
|
||||
/// </summary>
|
||||
Fixed32 = 5
|
||||
}
|
||||
|
||||
@ -80,6 +98,11 @@ namespace Google.Protobuf
|
||||
return (WireType) (tag & TagTypeMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given tag is an end group tag.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag to check.</param>
|
||||
/// <returns><c>true</c> if the given tag is an end group tag; <c>false</c> otherwise.</returns>
|
||||
public static bool IsEndGroupTag(uint tag)
|
||||
{
|
||||
return (WireType) (tag & TagTypeMask) == WireType.EndGroup;
|
||||
@ -99,64 +122,6 @@ namespace Google.Protobuf
|
||||
public static uint MakeTag(int fieldNumber, WireType wireType)
|
||||
{
|
||||
return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
|
||||
}
|
||||
|
||||
public static uint MakeTag(FieldDescriptor field)
|
||||
{
|
||||
return MakeTag(field.FieldNumber, GetWireType(field));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the wire type for the given field descriptor. This differs
|
||||
/// from GetWireType(FieldType) for packed repeated fields.
|
||||
/// </summary>
|
||||
internal static WireType GetWireType(FieldDescriptor descriptor)
|
||||
{
|
||||
return descriptor.IsPacked ? WireType.LengthDelimited : GetWireType(descriptor.FieldType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a field type to its wire type. Done with a switch for the sake
|
||||
/// of speed - this is significantly faster than a dictionary lookup.
|
||||
/// </summary>
|
||||
public static WireType GetWireType(FieldType fieldType)
|
||||
{
|
||||
switch (fieldType)
|
||||
{
|
||||
case FieldType.Double:
|
||||
return WireType.Fixed64;
|
||||
case FieldType.Float:
|
||||
return WireType.Fixed32;
|
||||
case FieldType.Int64:
|
||||
case FieldType.UInt64:
|
||||
case FieldType.Int32:
|
||||
return WireType.Varint;
|
||||
case FieldType.Fixed64:
|
||||
return WireType.Fixed64;
|
||||
case FieldType.Fixed32:
|
||||
return WireType.Fixed32;
|
||||
case FieldType.Bool:
|
||||
return WireType.Varint;
|
||||
case FieldType.String:
|
||||
return WireType.LengthDelimited;
|
||||
case FieldType.Group:
|
||||
return WireType.StartGroup;
|
||||
case FieldType.Message:
|
||||
case FieldType.Bytes:
|
||||
return WireType.LengthDelimited;
|
||||
case FieldType.UInt32:
|
||||
return WireType.Varint;
|
||||
case FieldType.SFixed32:
|
||||
return WireType.Fixed32;
|
||||
case FieldType.SFixed64:
|
||||
return WireType.Fixed64;
|
||||
case FieldType.SInt32:
|
||||
case FieldType.SInt64:
|
||||
case FieldType.Enum:
|
||||
return WireType.Varint;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("fieldType", "No such field type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user