| 2397 | return position, dec_flags, bytes_to_feed, bool(need_eof), chars_to_skip |
| 2398 | |
| 2399 | def tell(self): |
| 2400 | if not self._seekable: |
| 2401 | raise UnsupportedOperation("underlying stream is not seekable") |
| 2402 | if not self._telling: |
| 2403 | raise OSError("telling position disabled by next() call") |
| 2404 | self.flush() |
| 2405 | position = self.buffer.tell() |
| 2406 | decoder = self._decoder |
| 2407 | if decoder is None or self._snapshot is None: |
| 2408 | if self._decoded_chars: |
| 2409 | # This should never happen. |
| 2410 | raise AssertionError("pending decoded text") |
| 2411 | return position |
| 2412 | |
| 2413 | # Skip backward to the snapshot point (see _read_chunk). |
| 2414 | dec_flags, next_input = self._snapshot |
| 2415 | position -= len(next_input) |
| 2416 | |
| 2417 | # How many decoded characters have been used up since the snapshot? |
| 2418 | chars_to_skip = self._decoded_chars_used |
| 2419 | if chars_to_skip == 0: |
| 2420 | # We haven't moved from the snapshot point. |
| 2421 | return self._pack_cookie(position, dec_flags) |
| 2422 | |
| 2423 | # Starting from the snapshot position, we will walk the decoder |
| 2424 | # forward until it gives us enough decoded characters. |
| 2425 | saved_state = decoder.getstate() |
| 2426 | try: |
| 2427 | # Fast search for an acceptable start point, close to our |
| 2428 | # current pos. |
| 2429 | # Rationale: calling decoder.decode() has a large overhead |
| 2430 | # regardless of chunk size; we want the number of such calls to |
| 2431 | # be O(1) in most situations (common decoders, sensible input). |
| 2432 | # Actually, it will be exactly 1 for fixed-size codecs (all |
| 2433 | # 8-bit codecs, also UTF-16 and UTF-32). |
| 2434 | skip_bytes = int(self._b2cratio * chars_to_skip) |
| 2435 | skip_back = 1 |
| 2436 | assert skip_bytes <= len(next_input) |
| 2437 | while skip_bytes > 0: |
| 2438 | decoder.setstate((b'', dec_flags)) |
| 2439 | # Decode up to temptative start point |
| 2440 | n = len(decoder.decode(next_input[:skip_bytes])) |
| 2441 | if n <= chars_to_skip: |
| 2442 | b, d = decoder.getstate() |
| 2443 | if not b: |
| 2444 | # Before pos and no bytes buffered in decoder => OK |
| 2445 | dec_flags = d |
| 2446 | chars_to_skip -= n |
| 2447 | break |
| 2448 | # Skip back by buffered amount and reset heuristic |
| 2449 | skip_bytes -= len(b) |
| 2450 | skip_back = 1 |
| 2451 | else: |
| 2452 | # We're too far ahead, skip back a bit |
| 2453 | skip_bytes -= skip_back |
| 2454 | skip_back = skip_back * 2 |
| 2455 | else: |
| 2456 | skip_bytes = 0 |