33import mmap
44import sys
55import errno
6- import cStringIO
6+
7+ from cStringIO import StringIO
8+
9+ # in py 2.4, StringIO is only StringI, without write support.
10+ # Hence we must use the python implementation for this
11+ if sys .version_info [1 ] < 5 :
12+ from StringIO import StringIO
13+ # END handle python 2.4
714
815try :
916 import async .mod .zlib as zlib
@@ -73,6 +80,29 @@ def unpack_from(fmt, data, offset=0):
7380
7481#} END Aliases
7582
83+ #{ compatibility stuff ...
84+
85+ class _RandomAccessStringIO (object ):
86+ """Wrapper to provide required functionality in case memory maps cannot or may
87+ not be used. This is only really required in python 2.4"""
88+ __slots__ = '_sio'
89+
90+ def __init__ (self , buf = '' ):
91+ self ._sio = StringIO (buf )
92+
93+ def __getattr__ (self , attr ):
94+ return getattr (self ._sio , attr )
95+
96+ def __len__ (self ):
97+ return len (self .getvalue ())
98+
99+ def __getitem__ (self , i ):
100+ return self .getvalue ()[i ]
101+
102+ def __getslice__ (self , start , end ):
103+ return self .getvalue ()[start :end ]
104+
105+ #} END compatibility stuff ...
76106
77107#{ Routines
78108
@@ -94,7 +124,7 @@ def allocate_memory(size):
94124 # this of course may fail if the amount of memory is not available in
95125 # one chunk - would only be the case in python 2.4, being more likely on
96126 # 32 bit systems.
97- return cStringIO . StringIO ("\0 " * size )
127+ return _RandomAccessStringIO ("\0 " * size )
98128 # END handle memory allocation
99129
100130
@@ -109,15 +139,20 @@ def file_contents_ro(fd, stream=False, allow_mmap=True):
109139 try :
110140 if allow_mmap :
111141 # supports stream and random access
112- return mmap .mmap (fd , 0 , access = mmap .ACCESS_READ )
142+ try :
143+ return mmap .mmap (fd , 0 , access = mmap .ACCESS_READ )
144+ except EnvironmentError :
145+ # python 2.4 issue, 0 wants to be the actual size
146+ return mmap .mmap (fd , os .fstat (fd ).st_size , access = mmap .ACCESS_READ )
147+ # END handle python 2.4
113148 except OSError :
114149 pass
115150 # END exception handling
116151
117152 # read manully
118153 contents = os .read (fd , os .fstat (fd ).st_size )
119154 if stream :
120- return cStringIO . StringIO (contents )
155+ return _RandomAccessStringIO (contents )
121156 return contents
122157
123158def file_contents_ro_filepath (filepath , stream = False , allow_mmap = True , flags = 0 ):
0 commit comments