/base/Applications/More/More.cs
C# | 260 lines | 197 code | 37 blank | 26 comment | 52 complexity | 5956f8c989e1897b69bda1bba140cbbe MD5 | raw file
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Microsoft Research Singularity
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
-
- using System;
- using System.Collections;
- using System.Diagnostics;
- using System.IO;
-
- using Pipe = Microsoft.Singularity.Io.Tty;
- using FileSystem.Utils;
- using Microsoft.Contracts;
- using Microsoft.SingSharp.Reflection;
-
- using Microsoft.Singularity.Applications;
- using Microsoft.Singularity.Io;
- using Microsoft.Singularity.Directory;
- using Microsoft.Singularity.Configuration;
- using Microsoft.Singularity.Channels;
- [assembly: Transform(typeof(ApplicationResourceTransform))]
-
- namespace Microsoft.Singularity.Applications
- {
- [ConsoleCategory(HelpMessage="Display a screen full of text", DefaultAction=true)]
- internal class Parameters {
- [InputEndpoint("data")]
- public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
-
- [Endpoint]
- public readonly TRef<DirectoryServiceContract.Imp:Start> nsRef;
-
- [StringArrayParameter( "files", HelpMessage="Files to be listed.")]
- internal string[] fileSet;
-
- reflective internal Parameters();
-
- internal int AppMain() {
- return More.AppMain(this);
- }
- }
-
- class More
- {
- internal static int pageCounter;
- internal static Terminal! terminal;
- internal static long fileSize;
- internal static long bytesRead;
-
- [ Conditional("DEBUG_MORE") ]
- static void DebugPrint(string format, params object [] args)
- {
- DebugStub.Print(String.Format(format, args));
- }
-
- [ Conditional("DEBUG_MORE") ]
- static void DebugWriteLine(string format, params object [] args)
- {
- DebugPrint(format, args);
- DebugStub.Print("\n");
- }
-
- [ Conditional("DEBUG_MORE") ]
- static void DebugReadLine()
- {
- Console.ReadLine();
- }
-
- internal static int AppMain(Parameters! config) {
- // constants
-
- //int szLineCount = 0;
- int displayfile = 0;
- int consoleWidth = 0;
- int consoleHeight = 0;
- pageCounter = 0;
-
- terminal = new Terminal();
-
- DirectoryServiceContract.Imp dsRoot = ((!)config.nsRef).Acquire();
- if (dsRoot == null) {
- throw new Exception("Unable to acquire handle to the Directory Service root");
- }
-
- dsRoot.RecvSuccess();
-
- // TODO need to dynamically get window size
- consoleHeight = 47; // allow for "activity" line on top of Singularity console....
- consoleWidth = 79;
-
- assume config.fileSet != null;
- string szSrcLine;
- bool ok;
- if (config.fileSet.Length <= 0) {
- //stdin
- while ((szSrcLine = Console.ReadLine()) != null) {
- ok = PageText(szSrcLine, consoleHeight, consoleWidth, true);
- if (!ok) break;
- }
- delete dsRoot;
- return 0;
- }
-
- for (displayfile = 0; displayfile < config.fileSet.Length; displayfile++) {
- string filename = config.fileSet[displayfile];
- if (filename == null) continue;
-
- // check that file exists
- ErrorCode error;
- FileAttributesRecord fileAttributes;
- ok = FileUtils.GetAttributes(filename, dsRoot, out fileAttributes, out error);
- if (ok) {
- if (fileAttributes.Type == NodeType.IoMemory || fileAttributes.Type == NodeType.File) {
- fileSize = fileAttributes.FileSize;
-
- // Open file RO for now
- FileStream fsInput = new FileStream(dsRoot, filename, FileMode.Open, FileAccess.Read);
- StreamReader srInput = new StreamReader(fsInput);
- while ((szSrcLine = srInput.ReadLine()) != null) {
- ok = PageText(szSrcLine, consoleHeight, consoleWidth, false);
- if (!ok) break;
- }
- srInput.Close();
- fsInput.Close();
-
- // Display the file by pages
- // TODO: change PageText to return between pages so can recheck for
- // screen dimension changes (?)
-
- if (displayfile <= config.fileSet.Length - 2) // offset by 2 due to index offset plus increment hasn't happened yet
- {
- Console.WriteLine("");
- Console.Write("-- <ENTER> for next file --");
- int key;
- do {
- key = Console.Read();
- if (key == -1) {
- delete dsRoot;
- return 0;
- }
- } while ((char)key != '\n');
- }
- }
- else if (fileAttributes.Type == NodeType.Directory) {
- // check that it's not a directory
- Console.WriteLine("\n{0} - is a directory.", filename);
- }
- } // ok
- else {
- // not a directory, but file doesn't exist, print error message
- Console.WriteLine("\n{0} - file not found.", filename);
- }
- }
- delete dsRoot;
- return 0;
- }
-
- //////////////////////////////////////////////////////////////
- // Write out prompt and wait for input
- // After acquiring the input remove the prompt from the console
- //////////////////////////////////////////////////////////////
-
- static int GetInput(int PAGELENGTH, bool processingStdin)
- {
- int counter = 0;
- int key;
- if (processingStdin) {
- Console.Write("-- <more> -- ");
- key = Console.Read();
- if ((char)key == '\n' ) Console.Write("\n");
- }
- else {
- double temp = 0;
- if (fileSize != 0) {
- temp = (double) (bytesRead * 100) / (double)fileSize;
- }
- else {
- temp = 100;
- }
-
- Console.Write("-- <more> ({0}%) -- ", (int)temp);
- key = Console.Read();
- }
-
- // get rid of the -- <ENTER> line
- if ((char)key == '\n') {
- terminal.GenerateAndSendEscapeSequence(Pipe.EscapeCodes.UP);
- }
- Console.Write("\r");
- terminal.GenerateAndSendEscapeSequence(Pipe.EscapeCodes.ERASE_FROM_CURSOR);
-
- if (key == -1) return -1;
- switch (Char.ToLower((char)key)) {
- case 'q':
- return -1;
- default:
- if ((char)key == '\n') counter = PAGELENGTH ; // advance by 1
- break;
- }
- return counter;
- }
-
- // PageText - display text a page at a time
- static bool PageText(string! workString,
- int PAGELENGTH,
- int PAGEWIDTH,
- bool processingStdin)
- {
- string[] lines;
-
- int remainder = 0;
- int linesinline = 0;
-
- // Split the line into the requisite number of lines
- // needed based on page width
-
- if (workString.Length <= PAGEWIDTH) {
- lines = new string[1];
- lines[0] = workString;
- }
- else {
- int fullLines = workString.Length / PAGEWIDTH;
- remainder = workString.Length % PAGEWIDTH;
- linesinline = fullLines;
-
- if (remainder != 0) linesinline++;
- lines = new string[linesinline];
-
- int pos = 0;
- for (int i = 0; i < fullLines; i++) {
- lines[i] = workString.Substring(pos,PAGEWIDTH);
- pos += PAGEWIDTH;
- }
- if (remainder != 0) {
- lines[fullLines] = workString.Substring(pos);
- }
- }
-
- // write the lines out pausing where necessary
- for (int i = 0; i < lines.Length; i++) {
- string s = lines[i];
- assert s!= null;
- Console.WriteLine(s);
- pageCounter++;
- bytesRead += s.Length;
- if (pageCounter >= PAGELENGTH) {
- pageCounter = GetInput(PAGELENGTH, processingStdin);
- if (pageCounter == -1) return false;
- }
- }
- lines = null;
- return true;
- } // end of PageText
- }
- }