singrdk/base/Libraries/Console/ConsoleOutput.sg

456 lines
15 KiB
Plaintext
Raw Normal View History

2008-11-17 18:29:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: ConsoleOutput.sg
//
// Note: Uses /dev/conout to display console output.
//
namespace Microsoft.Singularity.Io
{
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.V1.Services;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using System;
using System.Text;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
public sealed class ConsoleOutput : ITracked
{
private static TContainer<ConsoleOutput> consoleContainer;
private struct PipeData : ITracked {
public UnicodePipeContract.Imp channel;
public void Dispose()
{
delete channel;
}
void ITracked.Acquire() {}
void ITracked.Release() {}
public void Expose() {}
public void UnExpose() {}
public UnicodePipeContract.Imp:READY Swap([Claims] UnicodePipeContract.Imp:READY newPipe) {
expose (this) {
UnicodePipeContract.Imp result = this.channel;
this.channel = newPipe;
return result;
}
}
}
//
//private struct DeviceData : ITracked {
// public ConsoleDeviceContract.Imp:Ready channel;
// public void Dispose()
// {
// delete channel;
// }
// void ITracked.Acquire() {}
// void ITracked.Release() {}
// public void Expose() {}
// public void UnExpose() {}
//}
//
private char[]! in ExHeap side;
private PipeData pipe;
//
//private DeviceData device;
//
private ConsoleOutput([Claims] UnicodePipeContract.Imp? pipe)
{
this.side = new[ExHeap] char [280];
this.pipe.channel = pipe;
}
private static UnicodePipeContract.Imp GetPipe()
{
UnicodePipeContract.Imp con = null;
Endpoint* in ExHeap pipeep = Process.GetStartupEndpoint(1);
if (pipeep != null) {
con = pipeep as UnicodePipeContract.Imp;
if (con == null) {
Process.RetStartupEndpoint(1,pipeep);
return null;
}
return con;
}
return null;
}
public static void Initialize()
{
//
//ConsoleDeviceContract.Imp imp = null;
//
//imp = OpenConsole("/dev/video-text");
//if (imp == null) {
// imp = OpenConsole("/dev/conout");
// if (imp == null) {
// DebugStub.Print("Couldn't open console.\n");
// return;
// }
//}
//
UnicodePipeContract.Imp pipe = GetPipe();
ConsoleOutput co = new ConsoleOutput(pipe);
consoleContainer = new TContainer<ConsoleOutput>(co);
}
public void Dispose()
{
this.pipe.Dispose();
// this.device.Dispose();
delete this.side;
}
void ITracked.Acquire() {
//Tracing.Log(Tracing.Debug,"ConsoleOutput.Acquire");
}
void ITracked.Release() {
//Tracing.Log(Tracing.Debug,"ConsoleOutput.Release");
}
void ITracked.Expose() {
//Tracing.Log(Tracing.Debug,"ConsoleOutput.Expose");
}
void ITracked.UnExpose() {
//Tracing.Log(Tracing.Debug,"ConsoleOutput.UnExpose");
}
public static void Finalize()
{
TContainer<ConsoleOutput> chandle = consoleContainer;
consoleContainer = null;
if (chandle == null) return;
ConsoleOutput co = chandle.Acquire();
if (co != null) co.Dispose();
}
//
//private static ConsoleDeviceContract.Imp
//OpenConsoleInternal(DirectoryServiceContract.Imp! nsImp,
// [Claims] char[]! in ExHeap deviceName)
//{
// ConsoleDeviceContract.Exp! exp;
// ConsoleDeviceContract.Imp! imp;
// ConsoleDeviceContract.NewChannel(out imp, out exp);
//
// nsImp.SendBind(deviceName, exp);
// switch receive {
// case nsImp.AckBind():
// return imp;
// break;
// case nsImp.NakBind(rejectImp, error):
// delete rejectImp;
// delete imp;
// break;
// case nsImp.ChannelClosed():
// throw new Exception("Channel closed during Console bind.");
// delete imp;
// break;
// case nsImp.NakBindReparse(path, rest, linked, backExp):
// assert linked == true;
// assert rest == null;
// delete backExp;
// delete imp;
//
// return OpenConsoleInternal(nsImp, path);
// break;
// }
// return null;
//}
//
//private static ConsoleDeviceContract.Imp OpenConsole(string! devName)
//{
// DirectoryServiceContract.Imp ns = DirectoryService.NewClientEndpoint();
// ConsoleDeviceContract.Imp imp =
// OpenConsoleInternal(ns, Bitter.FromString2(devName));
// delete ns;
//
// if (imp != null) {
// switch receive {
// case imp.Success():
// break;
// case imp.ContractNotSupported():
// throw new Exception("ConsoleOutput: ContractNotSupported");
// break;
// case imp.ChannelClosed():
// throw new Exception("ConsoleOutput: ChannelClosed");
// break;
// }
// }
// return imp;
//}
//
//public static void Clear()
//{
// if (consoleContainer == null) return;
//
// ConsoleOutput co = consoleContainer.Acquire();
//
// expose (co) {
// ConsoleDeviceContract.Imp ep = co.device.channel;
// if (ep != null) {
// ep.SendClear();
// switch receive {
// case ep.AckClear():
// break;
// case ep.NakClear():
// break;
// case ep.ChannelClosed():
// delete ep;
// co.device.channel = null;
// break;
// }
// }
// }
// consoleContainer.Release(co);
//}
//
//public static void CursorFlash()
//{
// if (consoleContainer == null) return;
//
// ConsoleOutput co = consoleContainer.Acquire();
//
// expose (co) {
// ConsoleDeviceContract.Imp ep = co.device.channel;
// if (ep != null) {
// ep.SendCursorFlash();
// switch receive {
// case ep.AckCursorFlash():
// break;
// case ep.NakCursorFlash():
// break;
// case ep.ChannelClosed():
// delete ep;
// co.device.channel = null;
// break;
// }
// }
// }
// consoleContainer.Release(co);
//}
//
//public static void CursorHide()
//{
// if (consoleContainer == null) return;
//
// ConsoleOutput co = consoleContainer.Acquire();
//
// expose (co) {
// ConsoleDeviceContract.Imp ep = co.device.channel;
// if (ep != null) {
// ep.SendCursorHide();
// switch receive {
// case ep.AckCursorHide():
// break;
// case ep.NakCursorHide():
// break;
// case ep.ChannelClosed():
// delete ep;
// co.device.channel = null;
// break;
// }
// }
// }
// consoleContainer.Release(co);
//}
//
//public static void CursorShow()
//{
// if (consoleContainer == null) return;
//
// ConsoleOutput co = consoleContainer.Acquire();
//
// expose (co) {
// ConsoleDeviceContract.Imp ep = co.device.channel;
// if (ep != null) {
// ep.SendCursorShow();
// switch receive {
// case ep.AckCursorShow():
// break;
// case ep.NakCursorShow():
// break;
// case ep.ChannelClosed():
// delete ep;
// co.device.channel = null;
// break;
// }
// }
// }
// consoleContainer.Release(co);
//}
//
public static char[]! in ExHeap Write([Claims] char[]! in ExHeap buffer,
int index, int count)
{
if (consoleContainer == null) return buffer;
ConsoleOutput co = consoleContainer.Acquire();
try {
expose (co) {
if (co.pipe.channel != null) {
return Write(buffer, index, count, ref co.pipe);
}
else {
return buffer;
}
}
}
finally {
consoleContainer.Release(co);
}
}
//
//private static char[]! in ExHeap Write([Claims] char[]! in ExHeap buffer,
// int index, int count,
// ref DeviceData device)
//{
// expose (device) {
// ConsoleDeviceContract.Imp channel = device.channel;
// if (channel != null) {
// channel.SendWrite(buffer, index, count);
// switch receive {
// case channel.AckWrite(localside):
// return localside;
//
// case channel.NakWrite(localside):
// return localside;
//
// case channel.ChannelClosed():
// delete channel;
// device.channel = null;
// return new[ExHeap] char[0];
// }
// }
// else {
// return buffer;
// }
// }
//}
//
private static char[]! in ExHeap Write([Claims] char[]! in ExHeap buffer,
int index, int count,
ref PipeData pipe)
{
expose (pipe) {
UnicodePipeContract.Imp channel = pipe.channel;
if (channel != null) {
// char[]! in ExHeap buffer=Bitter.FromString2(value);
channel.SendWrite(buffer, index, count);
switch receive {
case channel.AckWrite(i_buffer):
return i_buffer;
case channel.ChannelClosed():
delete channel;
pipe.channel = null;
return new[ExHeap] char[0];
case unsatisfiable:
DebugStub.Break();
throw new Exception("Pipe unsatisfiable ");
}
}
else {
return buffer;
}
}
}
public static void Write(char[]! buffer, int index, int count)
{
if (consoleContainer == null) return;
ConsoleOutput co = consoleContainer.Acquire();
expose (co) {
char[] in ExHeap side = co.side;
if (side.Length < count) {
delete side;
co.side = side = new[ExHeap] char [count];
}
for (int i = 0; i < count; i++) {
side[i] = buffer[index + i];
}
if (co.pipe.channel != null) {
co.side = Write(side, index, count, ref co.pipe);
}
//
//else {
// co.side = Write(side, index, count, ref co.device);
//}
//
}
consoleContainer.Release(co);
}
public static void Write(String! value)
{
if (consoleContainer == null) return;
ConsoleOutput co = consoleContainer.Acquire();
expose (co) {
char[] in ExHeap side = co.side;
if (side.Length < value.Length) {
delete side;
co.side = side = new[ExHeap] char [value.Length];
}
for (int i = 0; i < value.Length; i++) {
side[i] = value[i];
}
if (co.pipe.channel != null) {
co.side = Write(side, 0, value.Length, ref co.pipe);
}
//
//else {
// co.side = Write(side, 0, value.Length, ref co.device);
//}
//
}
consoleContainer.Release(co);
return;
}
public static UnicodePipeContract.Imp:READY Swap([Claims] UnicodePipeContract.Imp:READY newOutput) {
if (consoleContainer == null) {
delete newOutput;
return null;
}
ConsoleOutput co = consoleContainer.Acquire();
UnicodePipeContract.Imp result;
expose(co) {
result = co.pipe.Swap(newOutput);
}
consoleContainer.Release(co);
return result;
}
}
}