Skip to content
Snippets Groups Projects
Select Git revision
  • 44f3249018480c7ef14ff5fdc4a13462124c34e6
  • master default protected
  • arm-aarch-platform
  • arm-platform
  • vjpai-patch-3
  • vjpai-patch-1
  • v1.27.x
  • jtattermusch-patch-2
  • jtattermusch-patch-1
  • update-java-worker-example-in-performance-docs
  • revert-21805-revert-21797-reintroduce_21527
  • revert-21804-tls-credentials-1
  • zhen_cleanup_namecheck
  • revert-21806-revert-21767-revert-21725-revert-21680-cq_ordering
  • vjpai-patch-2
  • revert-21766-tls-credentials-1
  • revert-21640-change_local_tcp_security_level
  • revert-21680-cq_ordering
  • revert-21527-unify_boringssl_deps2
  • revert-20803-grpclb_stabilization
  • fix-kokoro-rvm-key
  • v1.27.0
  • v1.27.0-pre2
  • v1.27.0-pre1
  • v1.26.0
  • v1.26.0-pre1
  • v1.25.0
  • v1.25.0-pre1
  • v1.24.3
  • v1.24.2
  • v1.24.1
  • v1.23.1
  • v1.24.0
  • v1.24.0-pre2
  • v1.24.0-pre1
  • v1.22.1
  • v1.23.0
  • v1.23.0-pre1
  • v1.22.0
  • v1.22.0-pre1
  • v1.21.4
41 results

rpc_method.h

Blame
  • Metadata.cs 10.38 KiB
    #region Copyright notice and license
    // Copyright 2015, Google Inc.
    // All rights reserved.
    //
    // Redistribution and use in source and binary forms, with or without
    // modification, are permitted provided that the following conditions are
    // met:
    //
    //     * Redistributions of source code must retain the above copyright
    // notice, this list of conditions and the following disclaimer.
    //     * Redistributions in binary form must reproduce the above
    // copyright notice, this list of conditions and the following disclaimer
    // in the documentation and/or other materials provided with the
    // distribution.
    //     * Neither the name of Google Inc. nor the names of its
    // contributors may be used to endorse or promote products derived from
    // this software without specific prior written permission.
    //
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    #endregion
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Runtime.InteropServices;
    using System.Text;
    
    using Grpc.Core.Utils;
    
    namespace Grpc.Core
    {
        /// <summary>
        /// Provides access to read and write metadata values to be exchanged during a call.
        /// </summary>
        public sealed class Metadata : IList<Metadata.Entry>
        {
            /// <summary>
            /// All binary headers should have this suffix.
            /// </summary>
            public const string BinaryHeaderSuffix = "-bin";
    
            /// <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);
            }
    
            public void Insert(int index, Metadata.Entry item)
            {
                CheckWriteable();
                entries.Insert(index, item);
            }
    
            public void RemoveAt(int index)
            {
                CheckWriteable();
                entries.RemoveAt(index);
            }
    
            public Metadata.Entry this[int index]
            {
                get
                {
                    return entries[index];
                }
    
                set
                {
                    CheckWriteable();
                    entries[index] = value;
                }
            }
    
            public void Add(Metadata.Entry item)
            {
                CheckWriteable();
                entries.Add(item);
            }
    
            public void Add(string key, string value)
            {
                Add(new Entry(key, value));
            }
    
            public void Add(string key, byte[] valueBytes)
            {
                Add(new Entry(key, valueBytes));
            }
    
            public void Clear()
            {
                CheckWriteable();
                entries.Clear();
            }
    
            public bool Contains(Metadata.Entry item)
            {
                return entries.Contains(item);
            }
    
            public void CopyTo(Metadata.Entry[] array, int arrayIndex)
            {
                entries.CopyTo(array, arrayIndex);
            }
    
            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 string value;
                readonly byte[] valueBytes;
    
                private Entry(string key, string value, byte[] valueBytes)
                {
                    this.key = key;
                    this.value = value;
                    this.valueBytes = valueBytes;
                }
    
                /// <summary>
                /// Initializes a new instance of the <see cref="Grpc.Core.Metadata+Entry"/> struct with a binary value.
                /// </summary>
                /// <param name="key">Metadata key, needs to have suffix indicating a binary valued metadata entry.</param>
                /// <param name="valueBytes">Value bytes.</param>
                public Entry(string key, byte[] valueBytes)
                {
                    this.key = NormalizeKey(key);
                    Preconditions.CheckArgument(this.key.EndsWith(BinaryHeaderSuffix),
                        "Key for binary valued metadata entry needs to have suffix indicating binary value.");
                    this.value = null;
                    Preconditions.CheckNotNull(valueBytes, "valueBytes");
                    this.valueBytes = new byte[valueBytes.Length];
                    Buffer.BlockCopy(valueBytes, 0, this.valueBytes, 0, valueBytes.Length);  // defensive copy to guarantee immutability
                }
    
                /// <summary>
                /// Initializes a new instance of the <see cref="Grpc.Core.Metadata+Entry"/> struct holding an ASCII value.
                /// </summary>
                /// <param name="key">Metadata key, must not use suffix indicating a binary valued metadata entry.</param>
                /// <param name="value">Value string. Only ASCII characters are allowed.</param>
                public Entry(string key, string value)
                {
                    this.key = NormalizeKey(key);
                    Preconditions.CheckArgument(!this.key.EndsWith(BinaryHeaderSuffix),
                        "Key for ASCII valued metadata entry cannot have suffix indicating binary value.");
                    this.value = Preconditions.CheckNotNull(value, "value");
                    this.valueBytes = null;
                }
    
                /// <summary>
                /// Gets the metadata entry key.
                /// </summary>
                public string Key
                {
                    get
                    {
                        return this.key;
                    }
                }
    
                /// <summary>
                /// Gets the binary value of this metadata entry.
                /// </summary>
                public byte[] ValueBytes
                {
                    get
                    {
                        if (valueBytes == null)
                        {
                            return Encoding.GetBytes(value);
                        }
    
                        // defensive copy to guarantee immutability
                        var bytes = new byte[valueBytes.Length];
                        Buffer.BlockCopy(valueBytes, 0, bytes, 0, valueBytes.Length);
                        return bytes;
                    }
                }
    
                /// <summary>
                /// Gets the string value of this metadata entry.
                /// </summary>
                public string Value
                {
                    get
                    {
                        Preconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry");
                        return value ?? Encoding.GetString(valueBytes);
                    }
                }
    
                /// <summary>
                /// Returns <c>true</c> if this entry is a binary-value entry.
                /// </summary>
                public bool IsBinary
                {
                    get
                    {
                        return value == null;
                    }
                }
    
                /// <summary>
                /// Returns a <see cref="System.String"/> that represents the current <see cref="Grpc.Core.Metadata+Entry"/>.
                /// </summary>
                public override string ToString()
                {
                    if (IsBinary)
                    {
                        return string.Format("[Entry: key={0}, valueBytes={1}]", key, valueBytes);
                    }
                    
                    return string.Format("[Entry: key={0}, value={1}]", key, value);
                }
    
                /// <summary>
                /// Gets the serialized value for this entry. For binary metadata entries, this leaks
                /// the internal <c>valueBytes</c> byte array and caller must not change contents of it.
                /// </summary>
                internal byte[] GetSerializedValueUnsafe()
                {
                    return valueBytes ?? Encoding.GetBytes(value);
                }
    
                /// <summary>
                /// Creates a binary value or ascii value metadata entry from data received from the native layer.
                /// We trust C core to give us well-formed data, so we don't perform any checks or defensive copying.
                /// </summary>
                internal static Entry CreateUnsafe(string key, byte[] valueBytes)
                {
                    if (key.EndsWith(BinaryHeaderSuffix))
                    {
                        return new Entry(key, null, valueBytes);
                    }
                    return new Entry(key, Encoding.GetString(valueBytes), null);
                }
    
                private static string NormalizeKey(string key)
                {
                    return Preconditions.CheckNotNull(key, "key").ToLower();
                }
            }
        }
    }