[pypy-svn] r30819 - in pypy/dist/pypy/translator/cli: src test
antocuni at codespeak.net
antocuni at codespeak.net
Mon Jul 31 20:37:36 CEST 2006
Author: antocuni
Date: Mon Jul 31 20:37:20 2006
New Revision: 30819
Modified:
pypy/dist/pypy/translator/cli/src/ll_os.cs
pypy/dist/pypy/translator/cli/test/test_builtin.py
Log:
Added support for open/read/write of binary files.
Modified: pypy/dist/pypy/translator/cli/src/ll_os.cs
==============================================================================
--- pypy/dist/pypy/translator/cli/src/ll_os.cs (original)
+++ pypy/dist/pypy/translator/cli/src/ll_os.cs Mon Jul 31 20:37:20 2006
@@ -6,81 +6,162 @@
namespace pypy.builtin
{
+ interface IFile
+ {
+ FileStream GetStream();
+ void Write(string buffer);
+ string Read(int count);
+ }
+
+ class TextFile: IFile
+ {
+ private FileStream stream;
+ private TextWriter writer;
+ private TextReader reader;
+ public TextFile(FileStream stream, TextReader reader, TextWriter writer)
+ {
+ this.stream = stream;
+ this.writer = writer;
+ this.reader = reader;
+ }
+
+ public FileStream GetStream()
+ {
+ return stream;
+ }
+
+ public void Write(string buffer)
+ {
+ Debug.Assert(writer != null); // XXX: raise OSError?
+ writer.Write(buffer);
+ writer.Flush();
+ }
+
+ public string Read(int count)
+ {
+ Debug.Assert(reader != null); // XXX: raise OSError?
+ char[] buf = new char[count];
+ int n = reader.Read(buf, 0, count);
+ return new string(buf, 0, n);
+ }
+ }
+
+ class BinaryFile: IFile
+ {
+ private FileStream stream;
+ public BinaryFile(FileStream stream)
+ {
+ this.stream = stream;
+ }
+
+ public FileStream GetStream()
+ {
+ return stream;
+ }
+
+ public void Write(string buffer)
+ {
+ foreach(char ch in buffer)
+ stream.WriteByte((byte)ch);
+ stream.Flush();
+ }
+
+ public string Read(int count)
+ {
+ byte[] rawbuf = new byte[count];
+ int n = stream.Read(rawbuf, 0, count);
+ char[] buf = new char[count];
+ for(int i=0; i<count; i++)
+ buf[i] = (char)rawbuf[i];
+ return new string(buf, 0, n);
+ }
+ }
+
public class ll_os
{
- private static Dictionary<int, FileStream> FileDescriptors = new Dictionary<int, FileStream>();
- private static int fdcount = 2; // 0, 1 and 2 are already used by stdin, stdout and stderr
+ private static Dictionary<int, IFile> FileDescriptors;
+ private static int fdcount;
private const int O_RDONLY = 0;
private const int O_WRONLY = 1;
private const int O_RDWR = 2;
private const int O_CREAT = 64;
+ private const int O_TRUNC = 512;
private const int O_APPEND = 1024;
+ private const int O_BINARY = 32768;
private const int S_IFMT = 61440;
private const int S_IFDIR = 16384;
private const int S_IFREG = 32768;
+ static ll_os()
+ {
+ FileDescriptors = new Dictionary<int, IFile>();
+ FileDescriptors[0] = new TextFile(null, Console.In, null);
+ FileDescriptors[1] = new TextFile(null, null, Console.Out);
+ FileDescriptors[2] = new TextFile(null, null, Console.Error);
+ fdcount = 2; // 0, 1 and 2 are already used by stdin, stdout and stderr
+ }
+
public static string ll_os_getcwd()
{
return System.IO.Directory.GetCurrentDirectory();
}
- private static FileStream getfd(int fd)
+ private static IFile getfd(int fd)
{
- FileStream stream = FileDescriptors[fd];
- Debug.Assert(stream != null, string.Format("Invalid file descriptor: {0}", fd));
- return stream;
+ IFile f = FileDescriptors[fd];
+ Debug.Assert(f != null, string.Format("Invalid file descriptor: {0}", fd));
+ return f;
}
- public static int ll_os_open(string name, int flag, int mode)
+ private static FileAccess get_file_access(int flags)
{
- FileAccess f_access = FileAccess.Read;
- FileMode f_mode = FileMode.Open;
- if ((flag & O_RDWR) != 0) {
- f_access = FileAccess.ReadWrite;
- if ((flag & O_APPEND) != 0)
- f_mode = FileMode.Append;
- else
- f_mode = FileMode.Create;
- }
- else if ((flag & O_WRONLY) != 0) {
- f_access = FileAccess.Write;
- if ((flag & O_APPEND) != 0)
- f_mode = FileMode.Append;
- else
- f_mode = FileMode.Create;
- }
+ if ((flags & O_RDWR) != 0) return FileAccess.ReadWrite;
+ if ((flags & O_WRONLY) != 0) return FileAccess.Write;
+ return FileAccess.Read;
+ }
+
+ private static FileMode get_file_mode(int flags) {
+ if ((flags & O_APPEND) !=0 ) return FileMode.Append;
+ if ((flags & O_TRUNC) !=0 ) return FileMode.Truncate;
+ if ((flags & O_CREAT) !=0 ) return FileMode.CreateNew;
+ return FileMode.Open;
+ }
+
+ public static int ll_os_open(string name, int flags, int mode)
+ {
+ FileAccess f_access = get_file_access(flags);
+ FileMode f_mode = get_file_mode(flags);
+ FileStream stream = new FileStream(name, f_mode, f_access);
+ IFile f;
+
+ if ((flags & O_BINARY) != 0)
+ f = new BinaryFile(stream);
else {
- f_access = FileAccess.Read;
- if ((flag & O_CREAT) != 0)
- f_mode = FileMode.OpenOrCreate;
- else
- f_mode = FileMode.Open;
+ StreamWriter writer = null;
+ StreamReader reader = null;
+ if (f_access == FileAccess.Read || f_access == FileAccess.ReadWrite)
+ reader = new StreamReader(stream);
+ if (f_access == FileAccess.Write || f_access == FileAccess.ReadWrite)
+ writer = new StreamWriter(stream);
+ f = new TextFile(stream, reader, writer);
}
+
fdcount++;
- FileDescriptors[fdcount] = new FileStream(name, f_mode, f_access);
+ FileDescriptors[fdcount] = f;
return fdcount;
}
public static void ll_os_close(int fd)
{
- FileStream stream = getfd(fd);
+ FileStream stream = getfd(fd).GetStream();
stream.Close();
FileDescriptors.Remove(fd);
}
public static int ll_os_write(int fd, string buffer)
{
- if (fd == 1)
- Console.Write(buffer);
- else if (fd == 2)
- Console.Error.Write(buffer);
- else {
- FileStream stream = getfd(fd);
- StreamWriter w = new StreamWriter(stream);
- w.Write(buffer);
- w.Flush();
- }
+ getfd(fd).Write(buffer);
return buffer.Length;
}
@@ -91,16 +172,7 @@
public static string ll_os_read(int fd, int count)
{
- TextReader reader;
- if (fd == 0)
- reader = Console.In;
- else {
- FileStream stream = getfd(fd);
- reader = new StreamReader(stream);
- }
- char[] buf = new char[count];
- int n = reader.Read(buf, 0, count);
- return new string(buf, 0, n);
+ return getfd(fd).Read(count);
}
public static Record_Stat_Result ll_os_stat(string path)
@@ -128,7 +200,7 @@
public static Record_Stat_Result ll_os_fstat(int fd)
{
- FileStream stream = getfd(fd);
+ FileStream stream = getfd(fd).GetStream();
return ll_os_stat(stream.Name);
}
@@ -152,7 +224,7 @@
origin = SeekOrigin.End;
break;
}
- FileStream stream = getfd(fd);
+ FileStream stream = getfd(fd).GetStream();
return stream.Seek(offset, origin);
}
}
Modified: pypy/dist/pypy/translator/cli/test/test_builtin.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_builtin.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_builtin.py Mon Jul 31 20:37:20 2006
@@ -20,6 +20,19 @@
def test_os_read(self):
BaseTestRbuiltin.test_os_read(self)
+ def test_os_read_binary(self):
+ tmpfile = str(udir.udir.join("os_read_test"))
+ def fn():
+ from pypy.module.__builtin__.importing import BIN_READMASK
+ fd = os.open(tmpfile, BIN_READMASK, 0666)
+ res = os.read(fd, 4096)
+ os.close(fd)
+ return len(res)
+ f = file(tmpfile, 'w')
+ f.write('Hello\nWorld')
+ f.close()
+ assert self.interpret(fn, []) == len(file(tmpfile, 'rb').read())
+
# the following tests can't be executed with gencli because they
# returns file descriptors, and cli code is executed in another
# process. Instead of those, there is a new test that opens and
More information about the Pypy-commit
mailing list