[pypy-svn] r30358 - in pypy/dist/pypy/module/mmap: . test

rhymes at codespeak.net rhymes at codespeak.net
Sat Jul 22 16:18:03 CEST 2006


Author: rhymes
Date: Sat Jul 22 16:18:00 2006
New Revision: 30358

Modified:
   pypy/dist/pypy/module/mmap/interp_mmap.py
   pypy/dist/pypy/module/mmap/test/test_mmap.py
Log:
resize()

Modified: pypy/dist/pypy/module/mmap/interp_mmap.py
==============================================================================
--- pypy/dist/pypy/module/mmap/interp_mmap.py	(original)
+++ pypy/dist/pypy/module/mmap/interp_mmap.py	Sat Jul 22 16:18:00 2006
@@ -82,6 +82,13 @@
 
 libc.memmove.argtypes = [c_char_p, c_char_p, size_t]
 libc.memmove.restype = c_void_p
+has_mremap = False
+if hasattr(libc, "mremap"):
+    libc.mremap.argtypes = [c_void_p, size_t, size_t, c_ulong]
+    libc.mremap.restype = c_void_p
+    has_mremap = True
+libc.ftruncate.argtypes = [c_int, off_t]
+libc.ftruncate.restype = c_int
 
 if _POSIX:
     def _get_page_size():
@@ -425,6 +432,87 @@
         p = c_char_p(final_str)
         libc.memcpy(self._data, p, len(final_str))
     move.unwrap_spec = ['self', int, int, int]
+    
+    def resize(self, newsize):
+        self._check_valid()
+        
+        self._check_resizeable()
+        
+        if _POSIX:
+            if not has_mremap:
+                raise "mmap: resizing not available -- no mremap()"
+            
+            # resize the underlying file first
+            res = libc.ftruncate(self._fd, newsize)
+            if res == -1:
+                raise OperationError(self.space.w_EnvironmentError,
+                    self.space.wrap(_get_error_msg()))
+                
+            # now resize the mmap
+            MREMAP_MAYMOVE = 1
+            res = libc.mremap(cast(self._data, c_void_p), self._size, newsize,
+                MREMAP_MAYMOVE)
+            if res == -1:
+                raise OperationError(self.space.w_EnvironmentError,
+                    self.space.wrap(_get_error_msg()))
+            self._data = cast(res, POINTER(c_char))
+            self._size = newsize
+        # elif _MS_WINDOWS:
+        #     # disconnect the mapping
+        #     self._unmapview()
+        #     windll.kernel32.CloseHandle(self._map_handle)
+        # 
+        #     # move to the desired EOF position
+        #     if _64BIT:
+        #         newsize_high = wintypes.DWORD(newsize >> 32)
+        #         newsize_low = wintypes.DWORD(newsize & 0xFFFFFFFF)
+        #     else:
+        #         newsize_high = wintypes.DWORD(0)
+        #         newsize_low = wintypes.DWORD(newsize)
+        # 
+        #     FILE_BEGIN = wintypes.DWORD(0)
+        #     SetFilePointer = windll.kernel32.SetFilePointer
+        #     SetFilePointer.argtypes = [wintypes.HANDLE, wintypes.LONG,
+        #                                POINTER(wintypes.LONG), wintypes.DWORD]
+        #     SetFilePointer(self._file_handle,
+        #                    wintypes.LONG(newsize_low.value),    
+        #                    byref(wintypes.LONG(newsize_high.value)),
+        #                    FILE_BEGIN)
+        #     # resize the file
+        #     SetEndOfFile = windll.kernel32.SetEndOfFile
+        #     SetEndOfFile.argtypes = [wintypes.HANDLE]
+        #     SetEndOfFile(self._file_handle)
+        #     # create another mapping object and remap the file view
+        #     CreateFileMapping = windll.kernel32.CreateFileMappingA
+        #     CreateFileMapping.argtypes = [wintypes.HANDLE, c_void_p, wintypes.DWORD,
+        #                                   wintypes.DWORD, wintypes.DWORD, c_char_p]
+        #     CreateFileMapping.restype = wintypes.HANDLE
+        # 
+        #     self._map_handle = wintypes.HANDLE(CreateFileMapping(self._file_handle, None,
+        #                                                          _PAGE_READWRITE,
+        #                                                          newsize_high, newsize_low,
+        #                                                          self._tagname))
+        # 
+        #     dwErrCode = wintypes.DWORD(0)
+        #     if self._map_handle:
+        #         MapViewOfFile = windll.kernel32.MapViewOfFile
+        #         MapViewOfFile.argtypes = [wintypes.HANDLE, wintypes.DWORD,
+        #                                   wintypes.DWORD, wintypes.DWORD,
+        #                                   wintypes.DWORD]
+        #         MapViewOfFile.restype = c_void_p
+        #         self._data = MapViewOfFile(self._map_handle, _FILE_MAP_WRITE,
+        #                                    0, 0, 0)
+        #         if self._data:
+        #             self._data = cast(self._data, POINTER(c_char))
+        #             self._size = newsize
+        #             return
+        #         else:
+        #             dwErrCode = GetLastError()
+        #     else:
+        #         dwErrCode = GetLastError()
+        # 
+        #     raise WinError(dwErrCode)
+    resize.unwrap_spec = ['self', int]
 
 _mmap.typedef = TypeDef("_mmap",
     _to_str = interp2app(_mmap._to_str, unwrap_spec=_mmap._to_str.unwrap_spec),
@@ -449,6 +537,7 @@
         unwrap_spec=_mmap.write_byte.unwrap_spec),
     flush = interp2app(_mmap.flush, unwrap_spec=_mmap.flush.unwrap_spec),
     move = interp2app(_mmap.move, unwrap_spec=_mmap.move.unwrap_spec),
+    resize = interp2app(_mmap.resize, unwrap_spec=_mmap.resize.unwrap_spec),
 )
 
 def _check_map_size(space, size):

Modified: pypy/dist/pypy/module/mmap/test/test_mmap.py
==============================================================================
--- pypy/dist/pypy/module/mmap/test/test_mmap.py	(original)
+++ pypy/dist/pypy/module/mmap/test/test_mmap.py	Sat Jul 22 16:18:00 2006
@@ -269,22 +269,27 @@
         a = m.read(6)
         assert a == "frarar"
         m.close()
-#     
-#     def test_resize(self):
-#         if "darwin" in sys.platform or _FREEBSD:
-#             py.test.skip("resize does not work under OSX or FreeBSD")
-#         self.f = open(filename, "w+")
-#         self.f.write("foobar")
-#         m = mmap(self.f.fileno(), 6, access=cmmap.ACCESS_READ)
-#         py.test.raises(TypeError, m.resize, 1)
-#         m = mmap(self.f.fileno(), 6, access=cmmap.ACCESS_COPY)
-#         py.test.raises(TypeError, m.resize, 1)
-#         m = mmap(self.f.fileno(), 6, access=cmmap.ACCESS_WRITE)
-#         f_size = os.fstat(self.f.fileno()).st_size
-#         assert m.size() == f_size == 6
-#         m.resize(10)
-#         f_size = os.fstat(self.f.fileno()).st_size
-#         assert m.size() == f_size == 10
+    
+    def test_resize(self):
+        import sys
+        if ("darwin" in sys.platform) or ("freebsd" in sys.platform):
+            skip("resize does not work under OSX or FreeBSD")
+        
+        import mmap
+        import os
+        
+        f = open(filename, "w+")
+        f.write("foobar")
+        m = mmap(f.fileno(), 6, access=mmap.ACCESS_READ)
+        raises(TypeError, m.resize, 1)
+        m = mmap(f.fileno(), 6, access=mmap.ACCESS_COPY)
+        raises(TypeError, m.resize, 1)
+        m = mmap(f.fileno(), 6, access=mmap.ACCESS_WRITE)
+        f_size = os.fstat(f.fileno()).st_size
+        assert m.size() == f_size == 6
+        m.resize(10)
+        f_size = os.fstat(f.fileno()).st_size
+        assert m.size() == f_size == 10
 # 
 #     def test_len(self):
 #         m = mmap(self.f.fileno(), 6)



More information about the Pypy-commit mailing list