[Python-checkins] CVS: python/dist/src/Modules mmapmodule.c,2.12,2.13

A.M. Kuchling python-dev@python.org
Sat, 17 Jun 2000 21:45:16 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory slayer.i.sourceforge.net:/tmp/cvs-serv25421

Modified Files:
	mmapmodule.c 
Log Message:
Patch from Trent Mick: 
	The seek() method is broken for any 'whence' value (seek from
	start, current, orend) other than the default. I have a patch
	that fixes that as well as gets mmap'd files working on
	Linux64 and Win64.
	


Index: mmapmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v
retrieving revision 2.12
retrieving revision 2.13
diff -C2 -r2.12 -r2.13
*** mmapmodule.c	2000/06/18 04:25:08	2.12
--- mmapmodule.c	2000/06/18 04:45:14	2.13
***************
*** 46,50 ****
  #ifdef MS_WIN32
  	HANDLE	map_handle;
! 	HFILE	file_handle;
  	char *	tagname;
  #endif
--- 46,50 ----
  #ifdef MS_WIN32
  	HANDLE	map_handle;
! 	INT_PTR	file_handle;
  	char *	tagname;
  #endif
***************
*** 124,128 ****
          if (!PyArg_ParseTuple(args, ":read_byte"))
  		return NULL;
! 	if (self->pos >= 0 && self->pos < self->size) {
  	        where = self->data + self->pos;
  		value = (char) *(where);
--- 124,128 ----
          if (!PyArg_ParseTuple(args, ":read_byte"))
  		return NULL;
! 	if (self->pos < self->size) {
  	        where = self->data + self->pos;
  		value = (char) *(where);
***************
*** 154,158 ****
  		++eol;		/* we're interested in the position after the
  				   newline. */
! 	result = PyString_FromStringAndSize(start, (long) (eol - start));
  	self->pos += (eol - start);
  	return (result);
--- 154,158 ----
  		++eol;		/* we're interested in the position after the
  				   newline. */
! 	result = PyString_FromStringAndSize(start, (eol - start));
  	self->pos += (eol - start);
  	return (result);
***************
*** 183,192 ****
  		      PyObject *args)
  {
! 	long start = self->pos;
  	char * needle;
  	int len;
  
  	CHECK_VALID(NULL);
! 	if (!PyArg_ParseTuple (args, "s#|l", &needle, &len, &start)) {
  		return NULL;
  	} else {
--- 183,192 ----
  		      PyObject *args)
  {
! 	int start = self->pos;
  	char * needle;
  	int len;
  
  	CHECK_VALID(NULL);
! 	if (!PyArg_ParseTuple (args, "s#|i", &needle, &len, &start)) {
  		return NULL;
  	} else {
***************
*** 201,206 ****
  			if (!*n) {
  				return Py_BuildValue (
! 					"l",
! 					(long) (p - (self->data + start)));
  			}
  			p++;
--- 201,206 ----
  			if (!*n) {
  				return Py_BuildValue (
! 					"i",
! 					(int) (p - (self->data + start)));
  			}
  			p++;
***************
*** 256,260 ****
  
  #ifdef MS_WIN32
! 	if (self->file_handle != (HFILE) 0xFFFFFFFF) {
  		return (Py_BuildValue (
  			"l",
--- 256,260 ----
  
  #ifdef MS_WIN32
! 	if (self->file_handle != (INT_PTR) -1) {
  		return (Py_BuildValue (
  			"l",
***************
*** 402,422 ****
  mmap_seek_method (mmap_object * self, PyObject * args)
  {
! 	/* ptrdiff_t dist; */
! 	long dist;
  	int how=0;
  	CHECK_VALID(NULL);
! 	if (!PyArg_ParseTuple (args, "l|i", &dist, &how)) {
  		return(NULL);
  	} else {
! 		unsigned long where;
  		switch (how) {
! 		case 0:
  			where = dist;
  			break;
! 		case 1:
  			where = self->pos + dist;
  			break;
! 		case 2:
! 			where = self->size - dist;
  			break;
  		default:
--- 402,427 ----
  mmap_seek_method (mmap_object * self, PyObject * args)
  {
! 	int dist;
  	int how=0;
  	CHECK_VALID(NULL);
! 	if (!PyArg_ParseTuple (args, "i|i", &dist, &how)) {
  		return(NULL);
  	} else {
! 		size_t where;
  		switch (how) {
! 		case 0: /* relative to start */
! 			if (dist < 0)
! 				goto onoutofrange;
  			where = dist;
  			break;
! 		case 1: /* relative to current position */
! 			if ((int)self->pos + dist < 0)
! 				goto onoutofrange;
  			where = self->pos + dist;
  			break;
! 		case 2: /* relative to end */
! 			if ((int)self->size + dist < 0)
! 				goto onoutofrange;
! 			where = self->size + dist;
  			break;
  		default:
***************
*** 425,438 ****
  			return NULL;
  		}
! 		if ((where >= 0) && (where < (self->size))) {
! 			self->pos = where;
! 			Py_INCREF (Py_None);
! 			return (Py_None);
! 		} else {
! 			PyErr_SetString (PyExc_ValueError,
! 					 "seek out of range");
! 			return NULL;
! 		}
  	}
  }
  
--- 430,443 ----
  			return NULL;
  		}
! 		if (where > self->size)
! 			goto onoutofrange;
! 		self->pos = where;
! 		Py_INCREF (Py_None);
! 		return (Py_None);
  	}
+ 
+ onoutofrange:
+ 	PyErr_SetString (PyExc_ValueError, "seek out of range");
+ 	return NULL;
  }
  
***************
*** 705,708 ****
--- 710,770 ----
  };
  
+ 
+ /* extract the map size from the given PyObject
+ 
+    The map size is restricted to [0, INT_MAX] because this is the current
+    Python limitation on object sizes. Although the mmap object *could* handle
+    a larger map size, there is no point because all the useful operations
+    (len(), slicing(), sequence indexing) are limited by a C int.
+ 
+    Returns -1 on error, with an apprpriate Python exception raised. On
+    success, the map size is returned. */
+ static int
+ _GetMapSize(o)
+ 	PyObject *o;
+ {
+ 	if (PyInt_Check(o)) {
+ 		long i = PyInt_AsLong(o);
+ 		if (PyErr_Occurred())
+ 			return -1;
+ 		if (i < 0)
+ 			goto onnegoverflow;
+ 		if (i > INT_MAX)
+ 			goto onposoverflow;
+ 		return (int)i;
+ 	}
+ 	else if (PyLong_Check(o)) {
+ 		long i = PyLong_AsLong(o);
+ 		if (PyErr_Occurred()) {
+ 			/* yes negative overflow is mistaken for positive overflow
+ 			   but not worth the trouble to check sign of 'i' */
+ 			if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ 				goto onposoverflow;
+ 			else
+ 				return -1;
+ 		}
+ 		if (i < 0)
+ 			goto onnegoverflow;
+ 		if (i > INT_MAX)
+ 			goto onposoverflow;
+ 		return (int)i;
+ 	}
+ 	else {
+ 		PyErr_SetString(PyExc_TypeError,
+ 			"map size must be an integral value");
+ 		return -1;
+ 	}
+ 
+ onnegoverflow:
+ 	PyErr_SetString(PyExc_OverflowError,
+ 		"memory mapped size must be positive");
+ 	return -1;
+ 
+ onposoverflow:
+ 	PyErr_SetString(PyExc_OverflowError,
+ 		"memory mapped size is too large (limited by C int)");
+ 	return -1;
+ }
+ 
  #ifdef UNIX 
  static PyObject *
***************
*** 710,714 ****
  {
  	mmap_object * m_obj;
! 	unsigned long map_size;
  	int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ;
  	char * filename;
--- 772,777 ----
  {
  	mmap_object * m_obj;
! 	PyObject *map_size_obj = NULL;
! 	int map_size;
  	int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ;
  	char * filename;
***************
*** 717,725 ****
  
  	if (!PyArg_ParseTupleAndKeywords(args, kwdict, 
! 					 "il|ii", keywords, 
! 					 &fd, &map_size, &flags, &prot)
  		)
  		return NULL;
!   
  	m_obj = PyObject_New (mmap_object, &mmap_object_type);
  	if (m_obj == NULL) {return NULL;}
--- 780,791 ----
  
  	if (!PyArg_ParseTupleAndKeywords(args, kwdict, 
! 					 "iO|ii", keywords, 
! 					 &fd, &map_size_obj, &flags, &prot)
  		)
  		return NULL;
! 	map_size = _GetMapSize(map_size_obj);
! 	if (map_size < 0)
! 		return NULL;
! 	
  	m_obj = PyObject_New (mmap_object, &mmap_object_type);
  	if (m_obj == NULL) {return NULL;}
***************
*** 745,754 ****
  {
  	mmap_object * m_obj;
! 	unsigned long map_size;
  	char * tagname = "";
  
  	DWORD dwErr = 0;
  	int fileno;
! 	HFILE fh = 0;
  
  	/* Patch the object type */
--- 811,821 ----
  {
  	mmap_object * m_obj;
! 	PyObject *map_size_obj = NULL;
! 	int map_size;
  	char * tagname = "";
  
  	DWORD dwErr = 0;
  	int fileno;
! 	INT_PTR fh = 0;
  
  	/* Patch the object type */
***************
*** 756,766 ****
  
  	if (!PyArg_ParseTuple(args,
! 			  "il|z",
  			  &fileno,
! 			  &map_size,
  			  &tagname)
  		)
  		return NULL;
    
  	/* if an actual filename has been specified */
  	if (fileno != 0) {
--- 823,837 ----
  
  	if (!PyArg_ParseTuple(args,
! 			  "iO|z",
  			  &fileno,
! 			  &map_size_obj,
  			  &tagname)
  		)
  		return NULL;
    
+ 	map_size = _GetMapSize(map_size_obj);
+ 	if (map_size < 0)
+ 		return NULL;
+ 	
  	/* if an actual filename has been specified */
  	if (fileno != 0) {
***************
*** 785,789 ****
  	}
  	else {
! 		m_obj->file_handle = (HFILE) 0xFFFFFFFF;
  		m_obj->size = map_size;
  	}
--- 856,860 ----
  	}
  	else {
! 		m_obj->file_handle = (INT_PTR) -1;
  		m_obj->size = map_size;
  	}