[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