singrdk/base/Kernel/SingSharp.Runtime/Bitter.sg

488 lines
18 KiB
Plaintext
Raw Normal View History

2008-03-05 09:52:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: Bitter.sg
//
// Helper class for moving values in and out of byte vectors.
//
using System;
using System.Text;
using System.Threading;
using System.Runtime.CompilerServices; //StructAlign attribute
using System.Runtime.InteropServices; //structLayout attribute
using System.GCs;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.V1.Services;
using Microsoft.Singularity.V1.Threads;
using Allocation = Microsoft.Singularity.V1.Services.SharedHeapService.Allocation;
namespace Microsoft.Singularity
{
public class Bitter
{
private static void BoundsCheck(byte[] in ExHeap buffer, int offset, int length)
{
if (buffer == null) {
throw new ArgumentNullException("value");
}
if (offset < 0) {
throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_NeedNonNegNum");
}
if (offset + length > buffer.Length) {
throw new ArgumentOutOfRangeException("ArgumentOutOfRange_Index");
}
}
private static void BoundsCheck(char[] in ExHeap buffer, int offset, int length)
{
if (buffer == null) {
throw new ArgumentNullException("value");
}
if (offset < 0) {
throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_NeedNonNegNum");
}
if (offset + length > buffer.Length) {
throw new ArgumentOutOfRangeException("ArgumentOutOfRange_Index");
}
}
private static void BoundsCheck(byte[] buffer, int offset, int length)
{
if (buffer == null) {
throw new ArgumentNullException("value");
}
if (offset < 0) {
throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_NeedNonNegNum");
}
if (offset + length > buffer.Length) {
throw new ArgumentOutOfRangeException("ArgumentOutOfRange_Index");
}
}
public static unsafe UIntPtr ToAddress(byte[]! in ExHeap buffer, int offset)
{
unsafe {
return (UIntPtr)(byte *)&buffer[offset];
}
}
unsafe public static byte[]! ToByteArray(byte[]! in ExHeap buffer)
{
byte[] retval = new byte[buffer.Length];
int length = buffer.Length;
fixed (byte *pdst = &retval[0]) {
fixed (byte *psrc = &buffer[0]) {
Buffer.MoveMemory(pdst, psrc, length);
}
}
return retval;
}
public static unsafe void ToByteArray(byte[]! in ExHeap buffer, int offset,
int length, byte[]! array, int aoffset)
{
BoundsCheck(buffer, offset, length);
BoundsCheck(array, aoffset, length);
fixed (byte *pdst = &array[aoffset]) {
fixed (byte *psrc = &buffer[offset]) {
Buffer.MoveMemory(pdst, psrc, length);
}
}
}
public static unsafe void ToIoMemory(byte[] in ExHeap buffer, int offset,
int length, IoMemory memory, int aoffset)
{
if (buffer == null || memory == null ||
offset < 0 || offset + length > buffer.Length ||
aoffset < 0 || aoffset + length > memory.Length) {
throw new ArgumentOutOfRangeException("ArgumentOutOfRange_Index");
}
fixed (byte * src = &buffer[offset]) {
memory.Write8(aoffset, src, length);
}
}
public static unsafe char ToChar(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(char));
fixed (byte *ptr = &buffer[offset]) {
return *((char *)ptr);
}
}
public static unsafe short ToInt16(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(short));
fixed (byte *ptr = &buffer[offset]) {
return *((short *)ptr);
}
}
public static unsafe int ToInt32(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(int));
fixed (byte *ptr = &buffer[offset]) {
return *((int *)ptr);
}
}
public static unsafe long ToInt64(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(long));
fixed (byte *ptr = &buffer[offset]) {
return *((long *)ptr);
}
}
public static unsafe ushort ToUInt16(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(ushort));
fixed (byte *ptr = &buffer[offset]) {
return *((ushort *)ptr);
}
}
public static unsafe uint ToUInt32(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(uint));
fixed (byte *ptr = &buffer[offset]) {
return *((uint *)ptr);
}
}
public static unsafe ulong ToUInt64(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(ulong));
fixed (byte *ptr = &buffer[offset]) {
return *((ulong *)ptr);
}
}
public static unsafe float ToSingle(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(float));
fixed (byte *ptr = &buffer[offset]) {
return *((float *)ptr);
}
}
public static unsafe double ToDouble(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(double));
fixed (byte *ptr = &buffer[offset]) {
return *((double *)ptr);
}
}
public static unsafe bool ToBoolean(byte[]! in ExHeap buffer, int offset) {
BoundsCheck(buffer, offset, sizeof(int));
fixed (byte *ptr = &buffer[offset]) {
return *((int *)ptr) == 0 ? false : true;
}
}
// Converts a character vector to a managed string
public static unsafe string ToString(char[] in ExHeap chars)
{
if (chars == null) return null;
else {
char[]! in ExHeap nnChars = chars;
return ToString2(nnChars);
}
}
// Converts a character vector to a managed string
public static unsafe string! ToString2(char[]! in ExHeap chars,
int offset, int length)
{
if ((length == 0) || (chars.Length == 0))
{ return (!)String.Empty; } // happens before we have the String contract
DebugStub.Assert(offset < chars.Length);
DebugStub.Assert(offset + length <= chars.Length);
fixed (char *ptr = &chars[0]) {
// unnecessary cast, but because we have to build the
// runtime first before Kernel.Contracts.dll, we don't know
// that StringCTOR always returns non-null value.
return (!)String.StringCTOR(ptr, offset, length);
}
}
public static unsafe string! ToString2(char[]! in ExHeap chars)
{
return ToString2(chars, 0, chars.Length);
}
// Converts a byte vector to a managed string
public static unsafe string ToString(byte[] in ExHeap chars)
{
if (chars == null) return null;
else {
return ToString2(chars);
}
}
// Converts a character vector to a managed string
public static unsafe string! ToString2(byte[]! in ExHeap chars)
{
if (chars.Length == 0)
{ return (!)String.Empty; } // happens before we have the String contract
fixed (byte *ptr = &chars[0]) {
// unnecessary cast, but because we have to build the
// runtime first before Kernel.Contracts.dll, we don't know
// that StringCTOR always returns non-null value.
return (!)String.StringCTOR(ptr, 0, chars.Length);
}
}
public static byte[]! in ExHeap FromByteArray(byte[]! buffer)
{
byte[] in ExHeap retval = new[ExHeap] byte[buffer.Length];
int length = buffer.Length;
FromByteArray(retval, 0, length, buffer, 0);
return retval;
}
public static byte[]! in ExHeap
FromByteArray(byte[]! buffer, int offset, int length)
{
byte[] in ExHeap retval = new[ExHeap] byte[length];
FromByteArray(retval, 0, length, buffer, offset);
return retval;
}
public static unsafe void FromByteArray(byte[]! in ExHeap buffer,
int offset, int length,
byte[]! array, int aoffset)
{
BoundsCheck(buffer, offset, length);
BoundsCheck(array, aoffset, length);
fixed (byte *pdst = &buffer[offset]) {
fixed (byte *psrc = &array[aoffset]) {
Buffer.MoveMemory(pdst, psrc, length);
}
}
}
public static unsafe void FromIoMemory(byte[] in ExHeap buffer, int offset,
int length, IoMemory memory, int aoffset)
{
if (buffer == null || memory == null ||
offset < 0 || offset + length > buffer.Length ||
aoffset < 0 || aoffset + length > memory.Length) {
throw new ArgumentOutOfRangeException("ArgumentOutOfRange_Index");
}
fixed (byte * src = &buffer[offset]) {
memory.Read8(aoffset, src, length);
}
}
public static unsafe void FromChar(byte[]! in ExHeap buffer, int offset,
char value) {
BoundsCheck(buffer, offset, sizeof(char));
fixed (byte *ptr = &buffer[offset]) {
*((char *)ptr) = value;
}
}
public static unsafe void FromInt16(byte[]! in ExHeap buffer, int offset,
short value) {
BoundsCheck(buffer, offset, sizeof(short));
fixed (byte *ptr = &buffer[offset]) {
*((short *)ptr) = value;
}
}
public static unsafe void FromInt32(byte[]! in ExHeap buffer, int offset,
int value) {
BoundsCheck(buffer, offset, sizeof(int));
fixed (byte *ptr = &buffer[offset]) {
*((int *)ptr) = value;
}
}
public static unsafe void FromInt64(byte[]! in ExHeap buffer, int offset,
long value) {
BoundsCheck(buffer, offset, sizeof(long));
fixed (byte *ptr = &buffer[offset]) {
*((long *)ptr) = value;
}
}
public static unsafe void FromUInt16(byte[]! in ExHeap buffer, int offset,
ushort value) {
BoundsCheck(buffer, offset, sizeof(ushort));
fixed (byte *ptr = &buffer[offset]) {
*((ushort *)ptr) = value;
}
}
public static unsafe void FromUInt32(byte[]! in ExHeap buffer, int offset,
uint value) {
BoundsCheck(buffer, offset, sizeof(uint));
fixed (byte *ptr = &buffer[offset]) {
*((uint *)ptr) = value;
}
}
public static unsafe void FromUInt64(byte[]! in ExHeap buffer, int offset,
ulong value) {
BoundsCheck(buffer, offset, sizeof(ulong));
fixed (byte *ptr = &buffer[offset]) {
*((ulong *)ptr) = value;
}
}
public static unsafe void FromSingle(byte[]! in ExHeap buffer, int offset,
float value) {
BoundsCheck(buffer, offset, sizeof(float));
fixed (byte *ptr = &buffer[offset]) {
*((float *)ptr) = value;
}
}
public static unsafe void FromDouble(byte[]! in ExHeap buffer, int offset,
double value) {
BoundsCheck(buffer, offset, sizeof(double));
fixed (byte *ptr = &buffer[offset]) {
*((double *)ptr) = value;
}
}
public static unsafe void FromBoolean(byte[]! in ExHeap buffer, int offset,
bool value) {
BoundsCheck(buffer, offset, sizeof(int));
fixed (byte *ptr = &buffer[offset]) {
*((int *)ptr) = value ? 1 : 0;
}
}
// Converts a managed string to a char vector.
public static char[] in ExHeap FromString(string str)
{
if (str == null)
{ return null; }
return FromString2(str);
}
// Converts a managed string to a char vector.
public static char[]! in ExHeap FromString2(string! str)
{
return FromString2(str, 0, str.Length);
}
public static char[]! in ExHeap FromString2(string! str,
int start,
int length)
{
if (length == 0) {
return new [ExHeap] char[0];
}
else {
if (start + length > str.Length) {
length = str.Length - start;
}
char [] in ExHeap retval = new [ExHeap] char [length];
for (int i = 0; i < length; i++) {
retval[i] = str[start + i];
}
return retval;
}
}
public static unsafe void Copy(byte[]! in ExHeap dest,
int destOffset,
int length,
byte[]! in ExHeap source,
int sourceOffset)
{
BoundsCheck(source, sourceOffset, length);
BoundsCheck(dest, destOffset, length);
fixed (byte *pdst = &dest[destOffset]) {
fixed (byte *psrc = &source[sourceOffset]) {
Buffer.MoveMemory(pdst, psrc, length);
}
}
}
public static unsafe void Copy(char[]! in ExHeap dest,
int destOffset,
int length,
char[]! in ExHeap source,
int sourceOffset)
{
BoundsCheck(source, sourceOffset, length);
BoundsCheck(dest, destOffset, length);
fixed (char *pdst = &dest[destOffset]) {
fixed (char *psrc = &source[sourceOffset]) {
Buffer.MoveMemory((byte*)pdst, (byte*)psrc, length*sizeof(char));
}
}
}
public static unsafe void Zero(byte[]! in ExHeap dest,
int destOffset,
int length)
{
BoundsCheck(dest, destOffset, length);
fixed (byte *pdst = &dest[destOffset]) {
Buffer.ZeroMemory(pdst, length);
}
}
public static unsafe byte[]! in ExHeap
SplitOff(ref byte[]! in ExHeap original, int offset)
{
byte[]! in ExHeap vec = original;
return (byte[]! in ExHeap)SharedHeapService.Split(
(Allocation*)vec,
new UIntPtr(offset)
);
}
public static unsafe char[]! in ExHeap
SplitOff(ref char[]! in ExHeap original, int charOffset)
{
char[]! in ExHeap vec = original;
return (char[]! in ExHeap)SharedHeapService.Split(
(Allocation*)vec,
new UIntPtr(sizeof(char) * charOffset)
);
}
public static unsafe void Truncate(ref byte[]! in ExHeap buffer,
int newLength)
{
SharedHeapService.Truncate(
(Allocation*)buffer,
new UIntPtr(newLength)
);
}
public static unsafe void Truncate(ref char[]! in ExHeap buffer,
int newLength)
{
SharedHeapService.Truncate(
(Allocation*)buffer,
new UIntPtr(sizeof(char) * newLength)
);
}
}
}