jpayne@69
|
1 """ Python 'utf-16' Codec
|
jpayne@69
|
2
|
jpayne@69
|
3
|
jpayne@69
|
4 Written by Marc-Andre Lemburg (mal@lemburg.com).
|
jpayne@69
|
5
|
jpayne@69
|
6 (c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
|
jpayne@69
|
7
|
jpayne@69
|
8 """
|
jpayne@69
|
9 import codecs, sys
|
jpayne@69
|
10
|
jpayne@69
|
11 ### Codec APIs
|
jpayne@69
|
12
|
jpayne@69
|
13 encode = codecs.utf_16_encode
|
jpayne@69
|
14
|
jpayne@69
|
15 def decode(input, errors='strict'):
|
jpayne@69
|
16 return codecs.utf_16_decode(input, errors, True)
|
jpayne@69
|
17
|
jpayne@69
|
18 class IncrementalEncoder(codecs.IncrementalEncoder):
|
jpayne@69
|
19 def __init__(self, errors='strict'):
|
jpayne@69
|
20 codecs.IncrementalEncoder.__init__(self, errors)
|
jpayne@69
|
21 self.encoder = None
|
jpayne@69
|
22
|
jpayne@69
|
23 def encode(self, input, final=False):
|
jpayne@69
|
24 if self.encoder is None:
|
jpayne@69
|
25 result = codecs.utf_16_encode(input, self.errors)[0]
|
jpayne@69
|
26 if sys.byteorder == 'little':
|
jpayne@69
|
27 self.encoder = codecs.utf_16_le_encode
|
jpayne@69
|
28 else:
|
jpayne@69
|
29 self.encoder = codecs.utf_16_be_encode
|
jpayne@69
|
30 return result
|
jpayne@69
|
31 return self.encoder(input, self.errors)[0]
|
jpayne@69
|
32
|
jpayne@69
|
33 def reset(self):
|
jpayne@69
|
34 codecs.IncrementalEncoder.reset(self)
|
jpayne@69
|
35 self.encoder = None
|
jpayne@69
|
36
|
jpayne@69
|
37 def getstate(self):
|
jpayne@69
|
38 # state info we return to the caller:
|
jpayne@69
|
39 # 0: stream is in natural order for this platform
|
jpayne@69
|
40 # 2: endianness hasn't been determined yet
|
jpayne@69
|
41 # (we're never writing in unnatural order)
|
jpayne@69
|
42 return (2 if self.encoder is None else 0)
|
jpayne@69
|
43
|
jpayne@69
|
44 def setstate(self, state):
|
jpayne@69
|
45 if state:
|
jpayne@69
|
46 self.encoder = None
|
jpayne@69
|
47 else:
|
jpayne@69
|
48 if sys.byteorder == 'little':
|
jpayne@69
|
49 self.encoder = codecs.utf_16_le_encode
|
jpayne@69
|
50 else:
|
jpayne@69
|
51 self.encoder = codecs.utf_16_be_encode
|
jpayne@69
|
52
|
jpayne@69
|
53 class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
|
jpayne@69
|
54 def __init__(self, errors='strict'):
|
jpayne@69
|
55 codecs.BufferedIncrementalDecoder.__init__(self, errors)
|
jpayne@69
|
56 self.decoder = None
|
jpayne@69
|
57
|
jpayne@69
|
58 def _buffer_decode(self, input, errors, final):
|
jpayne@69
|
59 if self.decoder is None:
|
jpayne@69
|
60 (output, consumed, byteorder) = \
|
jpayne@69
|
61 codecs.utf_16_ex_decode(input, errors, 0, final)
|
jpayne@69
|
62 if byteorder == -1:
|
jpayne@69
|
63 self.decoder = codecs.utf_16_le_decode
|
jpayne@69
|
64 elif byteorder == 1:
|
jpayne@69
|
65 self.decoder = codecs.utf_16_be_decode
|
jpayne@69
|
66 elif consumed >= 2:
|
jpayne@69
|
67 raise UnicodeError("UTF-16 stream does not start with BOM")
|
jpayne@69
|
68 return (output, consumed)
|
jpayne@69
|
69 return self.decoder(input, self.errors, final)
|
jpayne@69
|
70
|
jpayne@69
|
71 def reset(self):
|
jpayne@69
|
72 codecs.BufferedIncrementalDecoder.reset(self)
|
jpayne@69
|
73 self.decoder = None
|
jpayne@69
|
74
|
jpayne@69
|
75 def getstate(self):
|
jpayne@69
|
76 # additional state info from the base class must be None here,
|
jpayne@69
|
77 # as it isn't passed along to the caller
|
jpayne@69
|
78 state = codecs.BufferedIncrementalDecoder.getstate(self)[0]
|
jpayne@69
|
79 # additional state info we pass to the caller:
|
jpayne@69
|
80 # 0: stream is in natural order for this platform
|
jpayne@69
|
81 # 1: stream is in unnatural order
|
jpayne@69
|
82 # 2: endianness hasn't been determined yet
|
jpayne@69
|
83 if self.decoder is None:
|
jpayne@69
|
84 return (state, 2)
|
jpayne@69
|
85 addstate = int((sys.byteorder == "big") !=
|
jpayne@69
|
86 (self.decoder is codecs.utf_16_be_decode))
|
jpayne@69
|
87 return (state, addstate)
|
jpayne@69
|
88
|
jpayne@69
|
89 def setstate(self, state):
|
jpayne@69
|
90 # state[1] will be ignored by BufferedIncrementalDecoder.setstate()
|
jpayne@69
|
91 codecs.BufferedIncrementalDecoder.setstate(self, state)
|
jpayne@69
|
92 state = state[1]
|
jpayne@69
|
93 if state == 0:
|
jpayne@69
|
94 self.decoder = (codecs.utf_16_be_decode
|
jpayne@69
|
95 if sys.byteorder == "big"
|
jpayne@69
|
96 else codecs.utf_16_le_decode)
|
jpayne@69
|
97 elif state == 1:
|
jpayne@69
|
98 self.decoder = (codecs.utf_16_le_decode
|
jpayne@69
|
99 if sys.byteorder == "big"
|
jpayne@69
|
100 else codecs.utf_16_be_decode)
|
jpayne@69
|
101 else:
|
jpayne@69
|
102 self.decoder = None
|
jpayne@69
|
103
|
jpayne@69
|
104 class StreamWriter(codecs.StreamWriter):
|
jpayne@69
|
105 def __init__(self, stream, errors='strict'):
|
jpayne@69
|
106 codecs.StreamWriter.__init__(self, stream, errors)
|
jpayne@69
|
107 self.encoder = None
|
jpayne@69
|
108
|
jpayne@69
|
109 def reset(self):
|
jpayne@69
|
110 codecs.StreamWriter.reset(self)
|
jpayne@69
|
111 self.encoder = None
|
jpayne@69
|
112
|
jpayne@69
|
113 def encode(self, input, errors='strict'):
|
jpayne@69
|
114 if self.encoder is None:
|
jpayne@69
|
115 result = codecs.utf_16_encode(input, errors)
|
jpayne@69
|
116 if sys.byteorder == 'little':
|
jpayne@69
|
117 self.encoder = codecs.utf_16_le_encode
|
jpayne@69
|
118 else:
|
jpayne@69
|
119 self.encoder = codecs.utf_16_be_encode
|
jpayne@69
|
120 return result
|
jpayne@69
|
121 else:
|
jpayne@69
|
122 return self.encoder(input, errors)
|
jpayne@69
|
123
|
jpayne@69
|
124 class StreamReader(codecs.StreamReader):
|
jpayne@69
|
125
|
jpayne@69
|
126 def reset(self):
|
jpayne@69
|
127 codecs.StreamReader.reset(self)
|
jpayne@69
|
128 try:
|
jpayne@69
|
129 del self.decode
|
jpayne@69
|
130 except AttributeError:
|
jpayne@69
|
131 pass
|
jpayne@69
|
132
|
jpayne@69
|
133 def decode(self, input, errors='strict'):
|
jpayne@69
|
134 (object, consumed, byteorder) = \
|
jpayne@69
|
135 codecs.utf_16_ex_decode(input, errors, 0, False)
|
jpayne@69
|
136 if byteorder == -1:
|
jpayne@69
|
137 self.decode = codecs.utf_16_le_decode
|
jpayne@69
|
138 elif byteorder == 1:
|
jpayne@69
|
139 self.decode = codecs.utf_16_be_decode
|
jpayne@69
|
140 elif consumed>=2:
|
jpayne@69
|
141 raise UnicodeError("UTF-16 stream does not start with BOM")
|
jpayne@69
|
142 return (object, consumed)
|
jpayne@69
|
143
|
jpayne@69
|
144 ### encodings module API
|
jpayne@69
|
145
|
jpayne@69
|
146 def getregentry():
|
jpayne@69
|
147 return codecs.CodecInfo(
|
jpayne@69
|
148 name='utf-16',
|
jpayne@69
|
149 encode=encode,
|
jpayne@69
|
150 decode=decode,
|
jpayne@69
|
151 incrementalencoder=IncrementalEncoder,
|
jpayne@69
|
152 incrementaldecoder=IncrementalDecoder,
|
jpayne@69
|
153 streamreader=StreamReader,
|
jpayne@69
|
154 streamwriter=StreamWriter,
|
jpayne@69
|
155 )
|