// 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();
}
}
}