aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/Grpc.Core/Metadata.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/csharp/Grpc.Core/Metadata.cs')
-rw-r--r--src/csharp/Grpc.Core/Metadata.cs177
1 files changed, 138 insertions, 39 deletions
diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs
index eccec26a61..4552d39d88 100644
--- a/src/csharp/Grpc.Core/Metadata.cs
+++ b/src/csharp/Grpc.Core/Metadata.cs
@@ -30,55 +30,163 @@
#endregion
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Collections.Specialized;
using System.Runtime.InteropServices;
using System.Text;
+using Grpc.Core.Utils;
+
namespace Grpc.Core
{
/// <summary>
- /// gRPC call metadata.
+ /// Provides access to read and write metadata values to be exchanged during a call.
/// </summary>
- public class Metadata
+ public sealed class Metadata : IList<Metadata.Entry>
{
- public static readonly Metadata Empty = new Metadata(ImmutableList<MetadataEntry>.Empty);
+ /// <summary>
+ /// An read-only instance of metadata containing no entries.
+ /// </summary>
+ public static readonly Metadata Empty = new Metadata().Freeze();
+
+ readonly List<Entry> entries;
+ bool readOnly;
+
+ public Metadata()
+ {
+ this.entries = new List<Entry>();
+ }
+
+ public Metadata(ICollection<Entry> entries)
+ {
+ this.entries = new List<Entry>(entries);
+ }
+
+ /// <summary>
+ /// Makes this object read-only.
+ /// </summary>
+ /// <returns>this object</returns>
+ public Metadata Freeze()
+ {
+ this.readOnly = true;
+ return this;
+ }
+
+ // TODO: add support for access by key
+
+ #region IList members
+
+ public int IndexOf(Metadata.Entry item)
+ {
+ return entries.IndexOf(item);
+ }
- readonly ImmutableList<MetadataEntry> entries;
+ public void Insert(int index, Metadata.Entry item)
+ {
+ CheckWriteable();
+ entries.Insert(index, item);
+ }
- public Metadata(ImmutableList<MetadataEntry> entries)
+ public void RemoveAt(int index)
{
- this.entries = entries;
+ CheckWriteable();
+ entries.RemoveAt(index);
}
- public ImmutableList<MetadataEntry> Entries
+ public Metadata.Entry this[int index]
{
get
{
- return this.entries;
+ return entries[index];
+ }
+
+ set
+ {
+ CheckWriteable();
+ entries[index] = value;
}
}
- public static Builder CreateBuilder()
+ public void Add(Metadata.Entry item)
+ {
+ CheckWriteable();
+ entries.Add(item);
+ }
+
+ public void Clear()
+ {
+ CheckWriteable();
+ entries.Clear();
+ }
+
+ public bool Contains(Metadata.Entry item)
+ {
+ return entries.Contains(item);
+ }
+
+ public void CopyTo(Metadata.Entry[] array, int arrayIndex)
{
- return new Builder();
+ entries.CopyTo(array, arrayIndex);
}
-
- public struct MetadataEntry
+
+ public int Count
+ {
+ get { return entries.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return readOnly; }
+ }
+
+ public bool Remove(Metadata.Entry item)
+ {
+ CheckWriteable();
+ return entries.Remove(item);
+ }
+
+ public IEnumerator<Metadata.Entry> GetEnumerator()
+ {
+ return entries.GetEnumerator();
+ }
+
+ IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return entries.GetEnumerator();
+ }
+
+ private void CheckWriteable()
+ {
+ Preconditions.CheckState(!readOnly, "Object is read only");
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Metadata entry
+ /// </summary>
+ public struct Entry
{
+ private static readonly Encoding Encoding = Encoding.ASCII;
+
readonly string key;
- readonly byte[] valueBytes;
+ string value;
+ byte[] valueBytes;
- public MetadataEntry(string key, byte[] valueBytes)
+ public Entry(string key, byte[] valueBytes)
{
- this.key = key;
- this.valueBytes = valueBytes;
+ this.key = Preconditions.CheckNotNull(key);
+ this.value = null;
+ this.valueBytes = Preconditions.CheckNotNull(valueBytes);
}
- public MetadataEntry(string key, string value)
+ public Entry(string key, string value)
{
- this.key = key;
- this.valueBytes = Encoding.ASCII.GetBytes(value);
+ this.key = Preconditions.CheckNotNull(key);
+ this.value = Preconditions.CheckNotNull(value);
+ this.valueBytes = null;
}
public string Key
@@ -89,38 +197,29 @@ namespace Grpc.Core
}
}
- // TODO: using ByteString would guarantee immutability.
public byte[] ValueBytes
{
get
{
- return this.valueBytes;
+ if (valueBytes == null)
+ {
+ valueBytes = Encoding.GetBytes(value);
+ }
+ return valueBytes;
}
}
- }
- public class Builder
- {
- readonly List<Metadata.MetadataEntry> entries = new List<Metadata.MetadataEntry>();
-
- public List<MetadataEntry> Entries
+ public string Value
{
get
{
- return entries;
+ if (value == null)
+ {
+ value = Encoding.GetString(valueBytes);
+ }
+ return value;
}
}
-
- public Builder Add(MetadataEntry entry)
- {
- entries.Add(entry);
- return this;
- }
-
- public Metadata Build()
- {
- return new Metadata(entries.ToImmutableList());
- }
}
}
}