singrdk/base/Libraries/FileSystem.Utils/FileUtils.sg

382 lines
12 KiB
Plaintext
Raw Permalink Normal View History

2008-03-05 09:52:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: FileUtils.sg
//
// Note:
//
using System;
using System.Text;
using System.Threading;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Directory;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.FileSystem;
using Microsoft.Singularity.V1.Services;
namespace FileSystem.Utils
{
public class FileUtils
{
public static object lockTarget = new object();
public static bool recording = false;
public static TimeSpan bindTime = new TimeSpan(0);
public static long bindCount = 0;
private static TRef<DirectoryServiceContract.Imp:Ready>! m_epNS =
new TRef<DirectoryServiceContract.Imp:Ready>(DirectoryService.NewClientEndpoint());
private static DirectoryServiceContract.Imp:Ready! GetDirectoryServiceContract()
{
return m_epNS.Acquire();
}
private static void ReleaseDirectoryServiceContract([Claims] DirectoryServiceContract.Imp:Ready! imp)
{
m_epNS.Release(imp);
}
public static FileContract.Imp:Ready OpenFile(string! filePath)
{
DirectoryServiceContract.Imp! rootNS = GetDirectoryServiceContract();
try {
return OpenFile(filePath, rootNS);
}
finally {
ReleaseDirectoryServiceContract(rootNS);
}
}
public static FileContract.Imp:Ready OpenFile(string! filePath, out ErrorCode error)
{
DirectoryServiceContract.Imp! rootNS = GetDirectoryServiceContract();
try {
return OpenFile(filePath, rootNS, out error);
}
finally {
ReleaseDirectoryServiceContract(rootNS);
}
}
public static FileContract.Imp:Ready OpenFile(string! filePath, DirectoryServiceContract.Imp! rootNS)
{
ErrorCode error;
return OpenFile(filePath, rootNS, out error);
}
public static FileContract.Imp:Ready OpenFile(string! filePath,
DirectoryServiceContract.Imp! rootNS,
out ErrorCode errorOut)
{
FileContract.Imp! fileClient;
FileContract.Exp! fileServer;
FileContract.NewChannel(out fileClient, out fileServer);
bool ok = SdsUtils.Bind(filePath, rootNS, fileServer, out errorOut);
if (!ok) {
2008-11-17 18:29:00 -05:00
//Console.WriteLine(" bind failed (error={0}) for {1}",
// SdsUtils.ErrorCodeToString(errorOut), filePath);
2008-03-05 09:52:00 -05:00
delete fileClient;
return null;
}
else {
}
fileClient.RecvSuccess();
return fileClient;
}
public static bool FileExists(DirectoryServiceContract.Imp:Ready! dsRoot,string! filePath)
{
ErrorCode error;
2008-11-17 18:29:00 -05:00
FileAttributesRecord fileAttributes;
return GetAttributes(filePath, dsRoot, out fileAttributes, out error);
2008-03-05 09:52:00 -05:00
}
#if !REMOVE
// REMOVE
public static int CreateFile(string! filePath)
{
2008-11-17 18:29:00 -05:00
ErrorCode errorCode;
2008-03-05 09:52:00 -05:00
DirectoryServiceContract.Imp! rootNS = DirectoryService.NewClientEndpoint();
try {
2008-11-17 18:29:00 -05:00
if (!CreateFile(filePath, rootNS, out errorCode)) return -1;
return 0;
}
finally {
delete rootNS;
}
}
// REMOVE
public static int CreateFile(string! filePath, out ErrorCode errorCode)
{
DirectoryServiceContract.Imp! rootNS = DirectoryService.NewClientEndpoint();
try {
if (!CreateFile(filePath, rootNS, out errorCode)) return -1;
return 0;
2008-03-05 09:52:00 -05:00
}
finally {
delete rootNS;
}
}
#endif
2008-11-17 18:29:00 -05:00
2008-03-05 09:52:00 -05:00
public static int CreateFile(string! filePath, DirectoryServiceContract.Imp! ds)
{
2008-11-17 18:29:00 -05:00
ErrorCode err;
if (!CreateFile(filePath,ds, out err)) return -1;
return 0;
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
2008-03-05 09:52:00 -05:00
public static bool CreateFile(string! filePath, DirectoryServiceContract.Imp! ds, out ErrorCode errorCode)
{
errorCode = ErrorCode.Unknown;
string fileName = PathUtils.FileFromPath(filePath);
if (fileName == null) {
// No trailing file part
return false;
}
DirectoryServiceContract.Imp dirClient = DirectoryUtils.FindDir(filePath, ds);
2008-11-17 18:29:00 -05:00
if (dirClient == null) {
2008-03-05 09:52:00 -05:00
// Couldn't open enclosing directory
return false;
}
dirClient.SendCreateFile(Bitter.FromString2(fileName));
switch receive {
case dirClient.NakCreateFile(error):
// Failure
errorCode = error;
delete dirClient;
return false;
case dirClient.AckCreateFile():
2008-11-17 18:29:00 -05:00
errorCode = ErrorCode.NoError;
2008-03-05 09:52:00 -05:00
// Success
break;
case dirClient.ChannelClosed():
// Channel closed unexpectedly
errorCode = ErrorCode.ChannelClosed;
delete dirClient;
return false;
}
delete dirClient;
return true;
} //createFile
// 0 is success
public static bool GetAttributes(string! filePath,
DirectoryServiceContract.Imp! ds,
2008-11-17 18:29:00 -05:00
out FileAttributesRecord fileAttributes,
2008-03-05 09:52:00 -05:00
out ErrorCode errorOut)
{
2008-11-17 18:29:00 -05:00
bool ok = SdsUtils.GetAttributes(filePath, ds, out fileAttributes, out errorOut);
2008-03-05 09:52:00 -05:00
return ok;
}
// 0 is success
public static bool GetAttributes(string! filePath,
2008-11-17 18:29:00 -05:00
out FileAttributesRecord fileAttributes,
2008-03-05 09:52:00 -05:00
out ErrorCode errorOut)
{
2008-11-17 18:29:00 -05:00
// make the complier happy and assign fileAttributes
fileAttributes = new FileAttributesRecord();
2008-03-05 09:52:00 -05:00
bool ok = false;
errorOut = ErrorCode.Unknown;
DirectoryServiceContract.Imp! rootNS = GetDirectoryServiceContract();
try {
2008-11-17 18:29:00 -05:00
ok = GetAttributes(filePath, rootNS, out fileAttributes, out errorOut);
2008-03-05 09:52:00 -05:00
}
catch (Exception e) {
2008-11-17 18:29:00 -05:00
DebugStub.WriteLine("FileUtils.GetAttributes exception: {0}", __arglist(e.Message));
2008-03-05 09:52:00 -05:00
}
finally {
ReleaseDirectoryServiceContract(rootNS);
}
return ok;
}
#if !REMOVE
// REMOVE version that does not have ep
public static int DeleteFile(string! filePath)
{
DirectoryServiceContract.Imp! ds = GetDirectoryServiceContract();
ErrorCode errorOut = ErrorCode.Unknown;
try {
DeleteFile(filePath, ds, out errorOut);
}
catch (Exception e) {
2008-11-17 18:29:00 -05:00
DebugStub.WriteLine("FileUtils.DeleteFile exception: {0}", __arglist(e.Message));
2008-03-05 09:52:00 -05:00
}
finally {
ReleaseDirectoryServiceContract(ds);
}
return (int) errorOut;
}
#endif
public static int DeleteFile(string! filePath, DirectoryServiceContract.Imp! ds, out ErrorCode errorOut )
{
string fileName = PathUtils.FileFromPath(filePath);
errorOut = ErrorCode.Unknown;
if (fileName == null) {
// No trailing filename
errorOut = ErrorCode.NotFound;
return -1;
}
DirectoryServiceContract.Imp dirClient = DirectoryUtils.FindDir(filePath, ds);
2008-11-17 18:29:00 -05:00
if (dirClient == null) {
2008-03-05 09:52:00 -05:00
// Couldn't open enclosing directory
errorOut = ErrorCode.NotFound;
return -1;
}
dirClient.SendDeleteFile(Bitter.FromString2(fileName));
switch receive {
case dirClient.NakDeleteFile(error):
errorOut = error;
// Failed; no such file?
delete dirClient;
return (int) errorOut;
case dirClient.AckDeleteFile():
errorOut = ErrorCode.NoError;
// Success
break;
case dirClient.ChannelClosed():
// Channel closed unexpectedly
errorOut = ErrorCode.ChannelClosed;
delete dirClient;
return (int) errorOut;
}
delete dirClient;
return 0;
} //DeleteFile
public static byte[] ReadEntireFile(
string! filePath,
DirectoryServiceContract.Imp! ds)
{
FileContract.Imp:Ready fileEP = OpenFile(filePath, ds);
if (fileEP == null) {
delete fileEP;
return null;
}
ErrorCode err;
2008-11-17 18:29:00 -05:00
FileAttributesRecord fileAttributes;
if (!GetAttributes(filePath, ds, out fileAttributes, out err)) {
2008-03-05 09:52:00 -05:00
delete fileEP;
return null;
}
2008-11-17 18:29:00 -05:00
byte[] data = new byte[fileAttributes.FileSize];
2008-03-05 09:52:00 -05:00
2008-11-17 18:29:00 -05:00
if (Read(fileEP, 0, (int)fileAttributes.FileSize, 0, data) != fileAttributes.FileSize) {
2008-03-05 09:52:00 -05:00
delete fileEP;
return null;
}
delete fileEP;
return data;
}
public static long Read(
FileContract.Imp:Ready! fileClient,
int bufOffset,
int readSize,
long fileOffset,
byte[]! buf)
{
long readCount = 0;
int error;
byte[]! in ExHeap readBytes = new[ExHeap] byte[readSize];
fileClient.SendRead(readBytes, 0, fileOffset, readBytes.Length);
fileClient.RecvAckRead(out readBytes, out readCount, out error);
if (error == 0) {
Bitter.ToByteArray(readBytes, 0, (int)readCount, buf, (int)bufOffset);
2008-11-17 18:29:00 -05:00
}
else {
2008-03-05 09:52:00 -05:00
readCount = 0;
}
delete readBytes;
return readCount;
}
public static long Write(
FileContract.Imp:Ready! fileClient,
int bufOffset,
int writeSize,
long fileOffset,
byte[]! buf)
{
long writeCount = 0;
int error;
byte[]! in ExHeap writeBytes = new[ExHeap] byte[writeSize];
Bitter.FromByteArray(writeBytes, 0, writeSize, buf, bufOffset);
fileClient.SendWrite(writeBytes, 0, fileOffset, writeSize);
fileClient.RecvAckWrite(out writeBytes, out writeCount, out error);
if (error != 0) {
writeCount = 0;
}
delete writeBytes;
return writeCount;
}
public static long Write(
FileContract.Imp:Ready! fileClient,
long offset,
byte[]! data)
{
return Write(fileClient, 0, data.Length, offset, data);
}
// we'll do something more intelligent than this later
public static long Write(
FileContract.Imp:Ready! fileClient,
long offset,
string! line) {
return Write(fileClient, offset, Encoding.UTF8.GetBytes(line));
}
public static long WriteLine(
FileContract.Imp:Ready! fileClient,
long offset,
string line) {
return Write(fileClient, offset, line+"\r\n");
}
}
}