singrdk/base/Services/Smb/Shared/Util.sg

427 lines
10 KiB
Plaintext

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
using System;
using System.Collections;
using System.Diagnostics;
using System.Text;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
#if ENABLE_GENERICS
using System.Collections.Generic;
#endif
namespace Smb.Shared
{
/*static*/ sealed class Util
{
private Util() {}
public static void ShowExceptionDebug(Exception! ex, string! msg)
{
DebugStub.WriteLine(msg);
ShowExceptionDebug(ex);
}
public static void ShowExceptionDebug(Exception! ex)
{
for (Exception current = ex; current != null; current = current.InnerException) {
Type! exType = current.GetType();
DebugStub.WriteLine(String.Format("{0}: {1}", exType.FullName, ex.Message));
}
}
public static string! ToStringDelete([Claims]char[]! in ExHeap exstring)
{
string! str = Bitter.ToString2(exstring);
delete exstring;
return str;
}
#if ENABLE_GENERICS
public static T[]! GetSubArray<T>(T[]! arr, int index, int length)
{
T[] result = new T[length];
Array.Copy(arr, index, result, 0, length);
return result;
}
#else
public static byte[]! GetSubArray(byte[]! arr, int index, int length)
requires index >= 0;
requires index + length <= arr.Length;
ensures result.Length == length;
{
byte[] result = new byte[length];
Array.Copy(arr, index, result, 0, length);
return result;
}
#endif
public const string HexDigits = "0123456789abcdef";
public static byte[]! HexStringToByteArray(string! str)
{
if ((str.Length % 2) != 0)
throw new Exception("Input string cannot be odd in length.");
byte[]! result = new byte[str.Length / 2];
for (int i = 0; i < result.Length; i++)
{
byte high = CharToHex(str[i * 2]);
byte low = CharToHex(str[i * 2 + 1]);
result[i] = (byte)((high << 4) | low);
}
return result;
}
/*
* Stupid C#!
*/
#if ENABLE_GENERICS && false
static int CompareArraySpans<T>(T[] array1, int offset1, T[] array2, int offset2, int length)
{
for (int i = 0; i < length; i++)
{
T element1 = array1[i];
T element2 = array2[i];
if (element1 < element2)
return -1;
if (element1 > element2)
return 1;
}
return 0;
}
#endif
public static int CompareArraySpans(byte[]! array1, int offset1, byte[]! array2, int offset2, int length)
{
for (int i = 0; i < length; i++)
{
byte element1 = array1[i];
byte element2 = array2[i];
if (element1 < element2)
return -1;
if (element1 > element2)
return 1;
}
return 0;
}
public static void DumpBuffer(byte[]! buffer)
{
DumpBuffer(buffer, 0, buffer.Length);
}
#if ENABLE_GENERICS
public static void DumpBuffer(ArraySpan<byte> span)
{
DumpBuffer(span.ContainingArray, span.Offset, span.Length);
}
#else
public static void DumpBuffer(ArraySpan_byte span)
{
DumpBuffer(span.ContainingArray, span.Offset, span.Length);
}
#endif
public static void DumpBuffer(byte[]! buffer, int index, int length)
{
StringBuilder line = new StringBuilder();
for (int i = 0; i < length; i += 0x10)
{
line.Length = 0;
line.AppendFormat("{0:x04}: ", i);
for (int j = 0; j < 0x10; j++)
{
if (i + j < length)
{
line.Append(" ");
byte b = buffer[index + i + j];
line.Append((Char)HexDigits[b >> 4]);
line.Append((Char)HexDigits[b & 0xf]);
}
else
{
line.Append(" ");
}
}
line.Append(" : ");
for (int j = 0; j < 0x10; j++)
{
if (i + j < length)
{
byte b = buffer[index + i + j];
if (b >= 32 && b <= 127)
{
line.Append((Char)b);
}
else
{
line.Append(".");
}
}
else
{
break;
}
}
DebugStub.WriteLine(line.ToString());
}
}
public static void DumpBuffer(byte[]! in ExHeap buffer)
{
DumpBuffer(buffer, 0, buffer.Length);
}
public static void DumpBuffer(byte[]! in ExHeap buffer, int index, int length)
{
StringBuilder line = new StringBuilder();
for (int i = 0; i < length; i += 0x10)
{
line.Length = 0;
line.AppendFormat("{0:x04}: ", i);
for (int j = 0; j < 0x10; j++)
{
if (i + j < length)
{
line.Append(" ");
byte b = buffer[index + i + j];
line.Append((Char)HexDigits[b >> 4]);
line.Append((Char)HexDigits[b & 0xf]);
}
else
{
line.Append(" ");
}
}
line.Append(" : ");
for (int j = 0; j < 0x10; j++)
{
if (i + j < length)
{
byte b = buffer[index + i + j];
if (b >= 32 && b <= 127)
{
line.Append((Char)b);
}
else
{
line.Append(".");
}
}
else
{
break;
}
}
DebugStub.WriteLine(line.ToString());
}
}
#if ENABLE_GENERICS
public static void CheckArraySpan<T>(T[] arr, int offset, int length)
{
if (arr == null)
throw new Exception("Array cannot be null.");
if (offset < 0)
throw new Exception("Array offset cannot be negative.");
if (length < 0)
throw new Exception("Array span length cannot be negative.");
if (offset + length > arr.Length)
throw new Exception("Array span exceeds size of array");
}
#endif
static void DumpHashtable(Hashtable! table)
{
try {
DebugStub.WriteLine("Hashtable:");
DebugStub.WriteLine("Keys:");
foreach (Object key in table.Keys)
{
if (key == null)
DebugStub.WriteLine(" null");
else {
Type keyType = key.GetType();
string keyTypeName = keyType.FullName;
string keyText = key.ToString();
DebugStub.WriteLine(String.Format(" ({0}) {1}", keyTypeName, keyText));
}
}
try {
DebugStub.WriteLine("Keys: (from array)");
object[]! keys = new object[table.Keys.Count];
table.Keys.CopyTo(keys, 0);
foreach (Object key2 in keys) {
if (key2 == null)
DebugStub.WriteLine(" null");
else {
Type keyType2 = key2.GetType();
string keyTypeName2 = keyType2.FullName;
string keyText2 = key2.ToString();
DebugStub.WriteLine(String.Format(" ({0}) {1}", keyTypeName2, keyText2));
}
}
} catch (Exception ex) {
DebugStub.WriteLine("Fault occurred while reading keys from array.");
Util.ShowExceptionDebug(ex);
}
DebugStub.WriteLine("Values:");
foreach (Object value in table.Values)
{
if (value == null)
DebugStub.WriteLine(" null");
else {
Type valueType = value.GetType();
string valueTypeName = valueType.FullName;
string valueText = value.ToString();
DebugStub.WriteLine(String.Format(" ({0}) {1}", valueTypeName, valueText));
}
}
} catch (Exception ex) {
Util.ShowExceptionDebug(ex);
}
}
public static string! ByteArrayToString(byte[]! buffer, int index, int length)
{
StringBuilder sb = new StringBuilder(length * 2);
for (int i = 0; i < length; i++)
{
byte b = buffer[index + i];
sb.Append(HexDigits[b >> 4]);
sb.Append(HexDigits[b & 0xf]);
}
return sb.ToString();
}
public static string! ByteArrayToStringHex(byte[]! buffer)
{
return ByteArrayToString(buffer, 0, buffer.Length);
}
public static string! ByteArrayToStringBitsBe(byte[]! buffer)
{
return ByteArrayToStringBitsBe(buffer, 0, buffer.Length);
}
public static string! ByteArrayToStringBitsBe(byte[]! buffer, int index, int length)
{
StringBuilder sb = new StringBuilder(length * 2);
sb.Append("be ");
for (int i = 0; i < length; i++)
{
if (i > 0)
sb.Append('.');
byte b = buffer[index + i];
for (int bit = 7; bit >= 0; bit--)
{
byte value = (byte)(b & (1 << bit));
sb.Append(value != 0 ? '1' : '0');
}
}
return sb.ToString();
}
public static string! ByteArrayToStringBitsLe(byte[]! buffer)
{
return ByteArrayToStringBitsLe(buffer, 0, buffer.Length);
}
public static string! ByteArrayToStringBitsLe(byte[]! buffer, int index, int length)
{
StringBuilder sb = new StringBuilder(length * 2);
sb.Append("le ");
for (int i = 0; i < length; i++)
{
if (i > 0)
sb.Append('.');
byte b = buffer[index + i];
for (int bit = 0; bit < 8; bit++)
{
byte value = (byte)(b & (1 << bit));
sb.Append(value != 0 ? '1' : '0');
}
}
return sb.ToString();
}
static byte CharToHex(char c)
{
if (c >= '0' && c <= '9')
return (byte)(c - '0');
if (c >= 'a' && c <= 'f')
return (byte)(c - 'a' + 10);
if (c >= 'A' && c <= 'F')
return (byte)(c - 'A' + 10);
throw new ArgumentException("Invalid hex char");
}
public static int Align4(int value)
{
return (value + 3) & ~3;
}
public static int Align2(int value)
{
return (value + 1) & ~1;
}
public static string! YesNoString(bool value)
{
return value ? "Yes" : "No";
}
}
class NotImplementedException : Exception
{
public NotImplementedException()
: base("Not Implemented")
{}
}
class UnsatisfiableReceiveException : Exception
{
public UnsatisfiableReceiveException()
: base("A 'switch receive' statement could not be satisfied.")
{}
public UnsatisfiableReceiveException(string! msg)
: base(msg)
{}
}
}