1
""" Python 'utf-8-sig' Codec
2
This work similar to UTF-8 with the following changes:
4
* On encoding/writing a UTF-8 encoded BOM will be prepended/written as the
7
* On decoding/reading if the first three bytes are a UTF-8 encoded BOM, these
14
def encode(input, errors='strict'):
15
return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0],
18
def decode(input, errors='strict'):
20
if input[:3] == codecs.BOM_UTF8:
23
34
34
(output, consumed) = codecs.utf_8_decode(input, errors, True)
24
return (output, consumed+prefix)
26
class IncrementalEncoder(codecs.IncrementalEncoder):
27
def __init__(self, errors='strict'):
28
codecs.IncrementalEncoder.__init__(self, errors)
31
def encode(self, input, final=False):
34
return codecs.BOM_UTF8 + \
35
codecs.utf_8_encode(input, self.errors)[0]
37
return codecs.utf_8_encode(input, self.errors)[0]
40
codecs.IncrementalEncoder.reset(self)
46
def setstate(self, state):
49
class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
50
def __init__(self, errors='strict'):
51
codecs.BufferedIncrementalDecoder.__init__(self, errors)
54
def _buffer_decode(self, input, errors, final):
57
if codecs.BOM_UTF8.startswith(input):
58
# not enough data to decide if this really is a BOM
59
# => try again on the next call
65
if input[:3] == codecs.BOM_UTF8:
66
(output, consumed) = \
67
codecs.utf_8_decode(input[3:], errors, final)
68
return (output, consumed+3)
69
return codecs.utf_8_decode(input, errors, final)
72
codecs.BufferedIncrementalDecoder.reset(self)
76
state = codecs.BufferedIncrementalDecoder.getstate(self)
77
# state[1] must be 0 here, as it isn't passed along to the caller
78
return (state[0], self.first)
80
def setstate(self, state):
81
# state[1] will be ignored by BufferedIncrementalDecoder.setstate()
82
codecs.BufferedIncrementalDecoder.setstate(self, state)
85
class StreamWriter(codecs.StreamWriter):
87
codecs.StreamWriter.reset(self)
90
except AttributeError:
93
def encode(self, input, errors='strict'):
94
self.encode = codecs.utf_8_encode
95
return encode(input, errors)
97
class StreamReader(codecs.StreamReader):
99
codecs.StreamReader.reset(self)
102
except AttributeError:
105
def decode(self, input, errors='strict'):
107
if codecs.BOM_UTF8.startswith(input):
108
# not enough data to decide if this is a BOM
109
# => try again on the next call
111
elif input[:3] == codecs.BOM_UTF8:
112
self.decode = codecs.utf_8_decode
113
(output, consumed) = codecs.utf_8_decode(input[3:],errors)
114
return (output, consumed+3)
115
# (else) no BOM present
116
self.decode = codecs.utf_8_decode
117
return codecs.utf_8_decode(input, errors)
119
### encodings module API
122
return codecs.CodecInfo(
126
incrementalencoder=IncrementalEncoder,
127
incrementaldecoder=IncrementalDecoder,
128
streamreader=StreamReader,
129
streamwriter=StreamWriter,