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