1.1 --- a/lib/posix/iconv.py Mon Dec 12 18:00:17 2016 +0100
1.2 +++ b/lib/posix/iconv.py Mon Dec 12 18:30:40 2016 +0100
1.3 @@ -20,7 +20,12 @@
1.4 """
1.5
1.6 from __builtins__.types import check_int, check_string
1.7 -from native import iconv_close, iconv_open, iconv
1.8 +from native import iconv, iconv_close, iconv_open, iconv_reset
1.9 +
1.10 +# Errors produced by iconv.
1.11 +
1.12 +EINVAL = 22
1.13 +EILSEQ = 84
1.14
1.15 class ConverterError(Exception):
1.16
1.17 @@ -28,10 +33,6 @@
1.18
1.19 pass
1.20
1.21 -E2BIG = 7
1.22 -EINVAL = 22
1.23 -EILSEQ = 84
1.24 -
1.25 class Converter:
1.26
1.27 "A character set converter."
1.28 @@ -43,6 +44,15 @@
1.29 check_string(from_encoding)
1.30 check_string(to_encoding)
1.31 self.__data__ = iconv_open(to_encoding, from_encoding)
1.32 + self.reset()
1.33 +
1.34 + def reset(self):
1.35 +
1.36 + "Reset the state of the converter."
1.37 +
1.38 + self.state = ["", 0, 0]
1.39 + self.result = []
1.40 + iconv_reset(self.__data__)
1.41
1.42 def close(self):
1.43
1.44 @@ -51,29 +61,53 @@
1.45 iconv_close(self.__data__)
1.46 self.__data__ = None
1.47
1.48 - def convert(self, s):
1.49 + def feed(self, s):
1.50
1.51 - "Convert 's' between the converter's encodings."
1.52 + "Feed 's' to the converter."
1.53
1.54 if self.__data__ is None:
1.55 raise ConverterError
1.56
1.57 check_string(s)
1.58
1.59 - result = []
1.60 - state = [0, len(s)]
1.61 + _s, start, remaining = self.state
1.62 +
1.63 + if _s:
1.64 + self.state = [_s + s, start, remaining + len(s)]
1.65 + else:
1.66 + self.state = [s, 0, len(s)]
1.67
1.68 while True:
1.69
1.70 # Obtain converted text and update the state.
1.71
1.72 - out = iconv(self.__data__, s, state)
1.73 - result.append(out)
1.74 + try:
1.75 + out = iconv(self.__data__, self.state)
1.76 +
1.77 + # Incomplete input does not cause an exception.
1.78 +
1.79 + except OSError, exc:
1.80 + if exc.value == EINVAL:
1.81 + self.result.append(exc.arg)
1.82 + return
1.83 + else:
1.84 + raise
1.85 +
1.86 + # Add any returned text to the result.
1.87 +
1.88 + self.result.append(out)
1.89
1.90 # Test for the end of the conversion.
1.91
1.92 - start, remaining = state
1.93 + _s, start, remaining = self.state
1.94 +
1.95 if not remaining:
1.96 - return "".join(result)
1.97 + return
1.98 +
1.99 + def __str__(self):
1.100 +
1.101 + "Return the value of the converted string."
1.102 +
1.103 + return "".join(self.result)
1.104
1.105 # vim: tabstop=4 expandtab shiftwidth=4