r"""Codec used when reading a file in universal newlines mode. It wraps another incremental decoder, translating \r\n and \r into \n. It also records the types of newlines encountered. When used with translate=False, it ensures that the newline sequence is returned in one piec
| 1900 | |
| 1901 | |
| 1902 | class IncrementalNewlineDecoder(codecs.IncrementalDecoder): |
| 1903 | r"""Codec used when reading a file in universal newlines mode. It wraps |
| 1904 | another incremental decoder, translating \r\n and \r into \n. It also |
| 1905 | records the types of newlines encountered. When used with |
| 1906 | translate=False, it ensures that the newline sequence is returned in |
| 1907 | one piece. |
| 1908 | """ |
| 1909 | def __init__(self, decoder, translate, errors='strict'): |
| 1910 | codecs.IncrementalDecoder.__init__(self, errors=errors) |
| 1911 | self.translate = translate |
| 1912 | self.decoder = decoder |
| 1913 | self.seennl = 0 |
| 1914 | self.pendingcr = False |
| 1915 | |
| 1916 | def decode(self, input, final=False): |
| 1917 | # decode input (with the eventual \r from a previous pass) |
| 1918 | if self.decoder is None: |
| 1919 | output = input |
| 1920 | else: |
| 1921 | output = self.decoder.decode(input, final=final) |
| 1922 | if self.pendingcr and (output or final): |
| 1923 | output = "\r" + output |
| 1924 | self.pendingcr = False |
| 1925 | |
| 1926 | # retain last \r even when not translating data: |
| 1927 | # then readline() is sure to get \r\n in one pass |
| 1928 | if output.endswith("\r") and not final: |
| 1929 | output = output[:-1] |
| 1930 | self.pendingcr = True |
| 1931 | |
| 1932 | # Record which newlines are read |
| 1933 | crlf = output.count('\r\n') |
| 1934 | cr = output.count('\r') - crlf |
| 1935 | lf = output.count('\n') - crlf |
| 1936 | self.seennl |= (lf and self._LF) | (cr and self._CR) \ |
| 1937 | | (crlf and self._CRLF) |
| 1938 | |
| 1939 | if self.translate: |
| 1940 | if crlf: |
| 1941 | output = output.replace("\r\n", "\n") |
| 1942 | if cr: |
| 1943 | output = output.replace("\r", "\n") |
| 1944 | |
| 1945 | return output |
| 1946 | |
| 1947 | def getstate(self): |
| 1948 | if self.decoder is None: |
| 1949 | buf = b"" |
| 1950 | flag = 0 |
| 1951 | else: |
| 1952 | buf, flag = self.decoder.getstate() |
| 1953 | flag <<= 1 |
| 1954 | if self.pendingcr: |
| 1955 | flag |= 1 |
| 1956 | return buf, flag |
| 1957 | |
| 1958 | def setstate(self, state): |
| 1959 | buf, flag = state |
no outgoing calls