[Zope-CVS] CVS: Products/AdaptableStorage/gateway_fs - FSConnection.py:1.17

Shane Hathaway shane@zope.com
Wed, 5 Mar 2003 11:47:26 -0500


Update of /cvs-repository/Products/AdaptableStorage/gateway_fs
In directory cvs.zope.org:/tmp/cvs-serv25709/gateway_fs

Modified Files:
	FSConnection.py 
Log Message:
FSConnection can now read/write files in text mode.  Next, the
gateways need to take advantage of this.


=== Products/AdaptableStorage/gateway_fs/FSConnection.py 1.16 => 1.17 ===
--- Products/AdaptableStorage/gateway_fs/FSConnection.py:1.16	Tue Mar  4 23:58:31 2003
+++ Products/AdaptableStorage/gateway_fs/FSConnection.py	Wed Mar  5 11:46:55 2003
@@ -32,12 +32,16 @@
 section_re = re.compile(r'^\[([^\[\]\n]+)\][^\r\n]*(?:\r\n|\r|\n)',
                       re.MULTILINE)
 
+# For a NODE_TYPE_SECTION, the value is 'f' (file) or 'd' (directory)
+NODE_TYPE_SECTION = '@node_type'
 
-NODE_TYPE_SECTION = '@node_type'  # Data is 'f' (file) or 'd' (directory)
-DATA_SECTION = '@data'  # Data is a string (file) or list of names (directory)
-SUGGESTED_EXTENSION_SECTION = '@s_ext'  # The suggested filename extension
-OBJECT_NAMES_SECTION = 'object_names'  # For directories
-REMAINDER_SECTION = 'remainder'
+# For a DATA_SECTION, the value is a two-item tuple containing a
+# string (file) or list of names (directory) and the as_text flag.
+DATA_SECTION = '@data'
+
+SUGGESTED_EXTENSION_SECTION = '@s_ext'  # The suggested filename extension.
+OBJECT_NAMES_SECTION = 'object_names'   # For directories.  The value is text.
+REMAINDER_SECTION = 'remainder'         # The value is a binary string.
 
 PROPERTIES_EXTENSION = 'properties'
 REMAINDER_EXTENSION = 'remainder'
@@ -190,8 +194,8 @@
         self._queue(subpath, NODE_TYPE_SECTION, data)
 
 
-    def writeData(self, subpath, data):
-        self._queue(subpath, DATA_SECTION, data)
+    def writeData(self, subpath, data, as_text=0):
+        self._queue(subpath, DATA_SECTION, (data, as_text))
 
 
     def suggestExtension(self, subpath, ext):
@@ -212,7 +216,7 @@
         return os.path.isdir(path) and 'd' or 'f'
 
 
-    def readData(self, subpath, allow_missing=0):
+    def readData(self, subpath, allow_missing=0, as_text=0):
         path = self._expandPath(subpath)
         isdir = os.path.isdir(path)
         # Read either the directory listing or the file contents.
@@ -221,8 +225,12 @@
             return self._listDirectoryAsMapping(path).values()
         else:
             # Return a string.
+            if as_text:
+                mode = 'rt'
+            else:
+                mode = 'rb'
             try:
-                f = open(path, 'rb')
+                f = open(path, mode)
             except IOError:
                 if allow_missing:
                     return None
@@ -334,10 +342,11 @@
         items = sections.items()
         items.sort()
         try:
-            for name, data in items:
+            for name, value in items:
                 if name == NODE_TYPE_SECTION:
                     continue
                 elif name == DATA_SECTION:
+                    data, as_text = value
                     if t == 'd':
                         # Change the list of subobjects.
                         self._removeUnlinkedItems(path, data)
@@ -349,7 +358,11 @@
                         self._dir_cache.invalidate(path)
                     else:
                         # Change the file contents.
-                        f = open(path, 'wb')
+                        if as_text:
+                            mode = 'wt'
+                        else:
+                            mode = 'wb'
+                        f = open(path, mode)
                         try:
                             f.write(data)
                         finally:
@@ -361,12 +374,12 @@
                     # Write to the remainder file.
                     if rem_f is None:
                         rem_f = open(rem_fn, 'wb')
-                    rem_f.write(data)
+                    rem_f.write(value)
                 else:
                     # Write a metadata section.
                     if props_f is None:
                         props_f = open(props_fn, 'wt')
-                    self._writeToProperties(props_f, name, data)
+                    self._writeToProperties(props_f, name, value)
         finally:
             self._closeOrDelete(props_f, props_fn)
             self._closeOrDelete(rem_f, rem_fn)
@@ -375,10 +388,10 @@
             self._dir_cache.invalidate(os.path.dirname(path))
 
 
-    def _writeToProperties(self, props_f, name, data):
+    def _writeToProperties(self, props_f, name, text):
         props_f.write('[%s]\n' % name)
-        props_f.write(data.replace('[', '[['))
-        if data.endswith('\n'):
+        props_f.write(text.replace('[', '[['))
+        if text.endswith('\n'):
             props_f.write('\n')
         else:
             props_f.write('\n\n')
@@ -462,13 +475,14 @@
             if non_containers.get(dir):
                 raise FSWriteError(
                     "Not a directory: %s" % dir)
+            data, as_text = sections[DATA_SECTION]
             if t == 'f':
                 if exists and os.path.isdir(path):
                     raise FSWriteError(
                         "Can't write file data to directory at %s"
                         % subpath)
                 non_containers[subpath] = 1
-                if not isinstance(sections[DATA_SECTION], StringType):
+                if not isinstance(data, StringType):
                     raise FSWriteError(
                         'Data for a file must be a string at %s'
                         % subpath)
@@ -477,12 +491,11 @@
                     raise FSWriteError(
                         "Can't write directory contents to file at %s"
                         % subpath)
-                items = sections[DATA_SECTION]
-                if isinstance(items, StringType):
+                if isinstance(data, StringType):
                     raise FSWriteError(
                         'Data for a directory must be a list or tuple at %s'
                         % subpath)
-                for item in items:
+                for item in data:
                     if not self._isLegalFilename(item):
                         raise FSWriteError(
                             'Not a legal object name: %s' % repr(item))