Use of a replacement to StringIO for managing encoding problems while marchalling Python objects.
This commit is contained in:
parent
36a740ed7e
commit
160c4960da
|
@ -37,6 +37,20 @@ class UnmarshalledFile:
|
||||||
self.content = '' # The binary content of the file of a file object
|
self.content = '' # The binary content of the file of a file object
|
||||||
self.size = 0 # The length of the file in bytes.
|
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
|
class Dummy: pass
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import xml.sax, difflib
|
import xml.sax, difflib
|
||||||
from xml.sax.handler import ContentHandler, ErrorHandler
|
from xml.sax.handler import ContentHandler, ErrorHandler
|
||||||
from xml.sax.xmlreader import InputSource
|
from xml.sax.xmlreader import InputSource
|
||||||
from StringIO import StringIO
|
from appy.shared import UnicodeBuffer
|
||||||
from appy.shared.errors import AppyError
|
from appy.shared.errors import AppyError
|
||||||
|
|
||||||
# Error-related constants ------------------------------------------------------
|
# Error-related constants ------------------------------------------------------
|
||||||
|
@ -343,24 +343,16 @@ class XmlMarshaller:
|
||||||
|
|
||||||
def dumpString(self, res, s):
|
def dumpString(self, res, s):
|
||||||
'''Dumps a string into the result.'''
|
'''Dumps a string into the result.'''
|
||||||
if hasattr(self, 'cdata') and self.cdata: res.write('<![CDATA[')
|
if self.cdata: res.write('<![CDATA[')
|
||||||
# Try to solve encoding problems
|
if isinstance(s, str):
|
||||||
try:
|
|
||||||
if hasattr(self, 'dumpUnicode') and self.dumpUnicode:
|
|
||||||
# Produce a unicode
|
|
||||||
s = s.decode('utf-8')
|
s = s.decode('utf-8')
|
||||||
else:
|
|
||||||
# Produce a str
|
|
||||||
s = s.decode('utf-8').encode('utf-8')
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
pass
|
|
||||||
# Replace special chars by XML entities
|
# Replace special chars by XML entities
|
||||||
for c in s:
|
for c in s:
|
||||||
if self.xmlEntities.has_key(c):
|
if self.xmlEntities.has_key(c):
|
||||||
res.write(self.xmlEntities[c])
|
res.write(self.xmlEntities[c])
|
||||||
else:
|
else:
|
||||||
res.write(c)
|
res.write(c)
|
||||||
if hasattr(self, 'cdata') and self.cdata: res.write(']]>')
|
if self.cdata: res.write(']]>')
|
||||||
|
|
||||||
def dumpFile(self, res, v):
|
def dumpFile(self, res, v):
|
||||||
'''Dumps a file into the result.'''
|
'''Dumps a file into the result.'''
|
||||||
|
@ -443,12 +435,15 @@ class XmlMarshaller:
|
||||||
res.write('</'); res.write(fieldName); res.write('>')
|
res.write('</'); res.write(fieldName); res.write('>')
|
||||||
|
|
||||||
def marshall(self, instance, objectType='popo'):
|
def marshall(self, instance, objectType='popo'):
|
||||||
'''Returns in a StringIO the XML version of p_instance. If p_instance
|
'''Returns in a UnicodeBuffer the XML version of p_instance. If
|
||||||
corresponds to a Plain Old Python Object, specify 'popo' for
|
p_instance corresponds to a Plain Old Python Object, specify 'popo'
|
||||||
p_objectType. If p_instance corresponds to an Archetypes object
|
for p_objectType. If p_instance corresponds to an Archetypes object
|
||||||
(Zope/Plone), specify 'archetype' for p_objectType. if p_instance is
|
(Zope/Plone), specify 'archetype' for p_objectType. if p_instance is
|
||||||
a Appy object, specify "appy" as p_objectType.'''
|
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
|
# Dump the XML prologue and root element
|
||||||
if objectType in ('archetype', 'appy'):
|
if objectType in ('archetype', 'appy'):
|
||||||
objectId = instance.UID() # ID in DB
|
objectId = instance.UID() # ID in DB
|
||||||
|
@ -508,9 +503,10 @@ class XmlMarshaller:
|
||||||
self.marshallSpecificElements(instance, res)
|
self.marshallSpecificElements(instance, res)
|
||||||
# Return the result
|
# Return the result
|
||||||
res.write('</'); res.write(self.rootElementName); res.write('>')
|
res.write('</'); res.write(self.rootElementName); res.write('>')
|
||||||
data = res.getvalue()
|
res = res.buffer
|
||||||
res.close()
|
if not self.dumpUnicode:
|
||||||
return data
|
res = res.encode('utf-8')
|
||||||
|
return res
|
||||||
|
|
||||||
def marshallSpecificElements(self, instance, res):
|
def marshallSpecificElements(self, instance, res):
|
||||||
'''You can use this marshaller as a base class for creating your own.
|
'''You can use this marshaller as a base class for creating your own.
|
||||||
|
|
Loading…
Reference in a new issue