// Copyright (c) All contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Buffers; using System.Collections; using System.Collections.Generic; namespace MessagePack { /// /// Internal utilities and extension methods for various external types. /// internal static class Utilities { /// /// A value indicating whether we're running on mono. /// internal static readonly bool IsMono = Type.GetType("Mono.RuntimeStructs") is Type; internal delegate void GetWriterBytesAction(ref MessagePackWriter writer, TArg argument); internal static byte[] GetWriterBytes(TArg arg, GetWriterBytesAction action, SequencePool pool) { using (var sequenceRental = pool.Rent()) { var writer = new MessagePackWriter(sequenceRental.Value); action(ref writer, arg); writer.Flush(); return sequenceRental.Value.AsReadOnlySequence.ToArray(); } } internal static Memory GetMemoryCheckResult(this IBufferWriter bufferWriter, int size = 0) { var memory = bufferWriter.GetMemory(size); if (memory.IsEmpty) { throw new InvalidOperationException("The underlying IBufferWriter.GetMemory(int) method returned an empty memory block, which is not allowed. This is a bug in " + bufferWriter.GetType().FullName); } return memory; } /// /// Gets an enumerator that does not allocate for each entry, /// and that doesn't produce the nullable ref annotation warning about unboxing a possibly null value. /// internal static NonGenericDictionaryEnumerable GetEntryEnumerator(this IDictionary dictionary) => new(dictionary); internal struct NonGenericDictionaryEnumerable { private IDictionary dictionary; internal NonGenericDictionaryEnumerable(IDictionary dictionary) { this.dictionary = dictionary; } public NonGenericDictionaryEnumerator GetEnumerator() => new(this.dictionary); } internal struct NonGenericDictionaryEnumerator : IEnumerator { private IDictionaryEnumerator enumerator; internal NonGenericDictionaryEnumerator(IDictionary dictionary) { this.enumerator = dictionary.GetEnumerator(); } public DictionaryEntry Current => this.enumerator.Entry; object IEnumerator.Current => this.enumerator.Entry; public void Dispose() { } public bool MoveNext() => this.enumerator.MoveNext(); public void Reset() => this.enumerator.Reset(); } } }