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