//
// Body of GPBinFiles interface.
// This file implements the code of the GPBinFiles.cp file.
// dwc August 1999. COOL version kjg May 2000
// kjg September 2000. Renamed from GPFiles to GPBinFiles.
// 
// Compile with: csc /t:library /r:GPFiles.dll GPBinFiles.cs
//
/* ------------------------------------------------------------ */
using System;
using GPFiles;

namespace GPBinFiles {
public class GPBinFiles {

  /* ----------------------------------	*/

  private static System.String mkStr(char[] arr) {
    int  ix = 0;
    char ch;
    do {
	ch = arr[ix]; ix++;
    } while (ch != '\0');
    return new System.String(arr,0,ix-1);
  }

  /* ----------------------------------	*/

  public static int length(FILE cpf) {
    return (int) cpf.length;
  }

  /* ----------------------------------	*/

  private static FILE open(System.String name) {
    try {
	FILE cpf = new FILE();
	cpf.file = new System.IO.File(name);
	cpf.bufS = new System.IO.BufferedStream(cpf.file.OpenRead());
        cpf.length = cpf.file.Length;
	return cpf;
    } catch {
	return null;
    }
  }
                               
  /* ----------------------------------	*/

  public static FILE findLocal(char[] fileName) 
  {
    System.String name = mkStr(fileName);
    return open(name);
  }
                               
  /* ----------------------------------	*/

  public static FILE findOnPath(
			char[] pathName, 
			char[] fileName) 
  { 
    //
    // Use mkStr, to trim space from end of char arrray.
    //
    System.String pName = mkStr(pathName);
    System.String fName = mkStr(fileName);
    System.String nName = "";

    System.String nextDir;
    System.String thisPath = System.Environment.GetEnvironmentVariable(pName);
//
//  System.Console.WriteLine(pName);
//  System.Console.WriteLine(thisPath);
//
    FILE cpf = new FILE();
    bool found = false; 
    bool pathFinished = false;
    int length = thisPath.Length;
    int nextLength;
    int nextPathStart;
    int nextPathEnd   = -1;

    while (!found && !pathFinished) {
      nextPathStart = nextPathEnd + 1;
      nextPathEnd   = thisPath.IndexOf(GPFiles.GPFiles.pathSep, nextPathStart);
      if (nextPathEnd < 0)
	  nextPathEnd = length;
      nextLength    = nextPathEnd - nextPathStart;
      nextDir = thisPath.Substring(nextPathStart, nextLength);
      nName = nextDir + GPFiles.GPFiles.fileSep + fName;
      found = System.IO.File.FileExists(nName);
      pathFinished = nextPathEnd >= length; 
    } 
    if (found) {
        return open(nName);
    } else
        return null;
  }
   
  /* ----------------------------------	*/

  public static char[] getFullPathName(FILE cpf) {
    return cpf.file.FullName.ToCharArray();
  }

  /* ----------------------------------	*/

  public static FILE openFile(char[] fileName) {
    System.String name = mkStr(fileName);
    return open(name);
  }
                               
  /* ----------------------------------	*/

  public static void CloseFile(FILE cpf) {
    if (cpf.bufS != null)
	cpf.bufS.Close();
  }

  /* ----------------------------------	*/

  public static FILE createFile(char[] arr) {
    FILE cpf = new FILE();
    try {
	cpf.file = new System.IO.File(mkStr(arr));
	cpf.bufS = new System.IO.BufferedStream(cpf.file.OpenWrite());
	return cpf;
    } catch {
	return null;
    }
  } 

  /* ----------------------------------	*/

  public static FILE createPath(char[] fileName)
  {
    System.String fName = mkStr(fileName);
    try {
	int ix = fName.LastIndexOf(GPFiles.GPFiles.fileSep);
	if (ix > 0) {
	    System.String path = fName.Substring(0,ix);
	    System.IO.Directory drct = new System.IO.Directory(path);
	    if (!drct.Exists)
		System.IO.Directories.CreateDirectories(path);
	    }
	FILE cpf = new FILE();
	cpf.file = new System.IO.File(fName);
	cpf.bufS = new System.IO.BufferedStream(cpf.file.OpenWrite());
	return cpf;
    } catch {
	return null;
    }
  }

  /* ----------------------------------	*/

  public static bool EOF(FILE cpf) {
    return cpf.bufS.Position >= cpf.length;
  }

  /* ----------------------------------	*/

  public static int readByte(FILE cpf) {
    if (cpf.bufS != null)
	return (int) cpf.bufS.ReadByte();
    else
	throw new System.Exception("File not open for reading");
  } 

  /* ----------------------------------	*/

  public static int  readNBytes(FILE cpf, 
				byte[] buff, 
				int    want)
  {
    if (cpf.bufS != null)
	return cpf.bufS.Read(buff, 0, want);
    else
	throw new System.Exception("File not open for reading");
  } 

  /* ----------------------------------	*/

  public static void WriteByte(FILE cpf, int b) {
    if (cpf.bufS != null)
	cpf.bufS.WriteByte((byte) b);
    else
	throw new System.Exception("File not open for reading");
  } 

  /* ----------------------------------	*/

  public static void WriteNBytes(FILE cpf,
				 byte[] buff,
				 int    want)
  {
    if (cpf.bufS != null)
	cpf.bufS.Write(buff, 0, want);
    else
	throw new System.Exception("File not open for reading");
  } 
}	// end of class GPBinFiles

/* ------------------------------------------------------------ */
/*		File-descriptor for GPBinFiles			*/
/* ------------------------------------------------------------ */

  public class FILE : GPFiles.FILE
  {
     public System.IO.BufferedStream bufS;
     public long length;
  }	// end of class FILE

/* ------------------------------------------------------------ */
} // end of GPBinFiles.
/* ------------------------------------------------------------ */

