diff --git a/shared/__init__.py b/shared/__init__.py index 73e16a2..64ee52d 100755 --- a/shared/__init__.py +++ b/shared/__init__.py @@ -37,6 +37,20 @@ class UnmarshalledFile: self.content = '' # The binary content of the file of a file object self.size = 0 # The length of the file in bytes. +class UnicodeBuffer: + '''With StringIO class, I have tons of encoding problems. So I define a + similar class here, that uses an internal unicode buffer.''' + def __init__(self): + self.buffer = u'' + def write(self, s): + if s == None: return + if isinstance(s, unicode): + self.buffer += s + elif isinstance(s, str): + self.buffer += s.decode('utf-8') + else: + self.buffer += unicode(s) + # ------------------------------------------------------------------------------ class Dummy: pass # ------------------------------------------------------------------------------ diff --git a/shared/xml_parser.py b/shared/xml_parser.py index 76b3307..8590106 100755 --- a/shared/xml_parser.py +++ b/shared/xml_parser.py @@ -20,7 +20,7 @@ import xml.sax, difflib from xml.sax.handler import ContentHandler, ErrorHandler from xml.sax.xmlreader import InputSource -from StringIO import StringIO +from appy.shared import UnicodeBuffer from appy.shared.errors import AppyError # Error-related constants ------------------------------------------------------ @@ -343,24 +343,16 @@ class XmlMarshaller: def dumpString(self, res, s): '''Dumps a string into the result.''' - if hasattr(self, 'cdata') and self.cdata: res.write('') + if self.cdata: res.write(']]>') def dumpFile(self, res, v): '''Dumps a file into the result.''' @@ -443,12 +435,15 @@ class XmlMarshaller: res.write('') def marshall(self, instance, objectType='popo'): - '''Returns in a StringIO the XML version of p_instance. If p_instance - corresponds to a Plain Old Python Object, specify 'popo' for - p_objectType. If p_instance corresponds to an Archetypes object + '''Returns in a UnicodeBuffer the XML version of p_instance. If + p_instance corresponds to a Plain Old Python Object, specify 'popo' + for p_objectType. If p_instance corresponds to an Archetypes object (Zope/Plone), specify 'archetype' for p_objectType. if p_instance is a Appy object, specify "appy" as p_objectType.''' - res = StringIO() + if not hasattr(self, 'cdata'): + # The constructor has not been called. Do it now. + XmlMarshaller.__init__(self) + res = UnicodeBuffer() # Dump the XML prologue and root element if objectType in ('archetype', 'appy'): objectId = instance.UID() # ID in DB @@ -508,9 +503,10 @@ class XmlMarshaller: self.marshallSpecificElements(instance, res) # Return the result res.write('') - data = res.getvalue() - res.close() - return data + res = res.buffer + if not self.dumpUnicode: + res = res.encode('utf-8') + return res def marshallSpecificElements(self, instance, res): '''You can use this marshaller as a base class for creating your own.